Haskell-OpenAPI-Code-Generator/Stripe-Haskell-Library

NotificationEventDataObject' is empty

joel-bach opened this issue · 11 comments

The type NotificationEventDataObject' (https://hackage.haskell.org/package/stripeapi-0.1.0.2/docs/StripeAPI-Types-NotificationEventData.html#t:NotificationEventDataObject-39-) is empty and therefore not usable to extract information from the response. The relevant part from the Stripe specification is the following:

    notification_event_data:
      description: ''
      properties:
        object:
          description: Object containing the API resource relevant to the event. For
            example, an `invoice.created` event will have a full [invoice object](https://stripe.com/docs/api#invoice_object)
            as the value of the object key.
          type: object
        previous_attributes:
          description: Object containing the names of the attributes that have changed,
            and their previous values (sent along only with *.updated events).
          type: object
      required:
      - object
      title: NotificationEventData
      type: object
      x-expandableFields: []

The generated code corresponds to the specification but is not usable nevertheless. One possible solution would be to adjust the generator to use Data.Aeson.Value instead of unit types.

@joelfisch As far as I understand, this should be a json object with two keys: object and previous_attributes. No?
So the generator is just entirely wrong, or am I misunderstanding that?

Yes, there are exactly those two keys on the record called NotificationEventDataSource : https://hackage.haskell.org/package/stripeapi-0.1.0.2/docs/StripeAPI-Types-NotificationEventData.html#t:NotificationEventData

The unit subtype NotificationEventDataObject' we are talking about is the first of those sub-properties. And this is empty as to the specification (type object without any properties).

Ah yes!

So is the spec wrong (because the object won't be empty) or are we interpreting the spec wrong (empty specification could mean full object)?

As far as I know the spec is wrong. They would have to define the properties or use the additionalProperties field.
Regarding generation: I think the best we can do is to replace empty objects with Data.Aeson.Value or Data.Aeson.Object as this allows the users to work with the data to some extent. IMO it would somewhat ok as nobody really has a benefit of working with an empty object even if the person would create such a type on purpose. What do you think @NorfairKing ?

If the spec is wrong, I'd like to ask stripe about that. Do we have a way to contact them?
If the spec is wrong but the generation is right, let's also look at the docs as well: https://stripe.com/docs/api/events/object.

However, I think that maybe we interpret the spec wrong. I think that this:

          description: Object containing the API resource relevant to the event. For
            example, an `invoice.created` event will have a full [invoice object](https://stripe.com/docs/api#invoice_object)
            as the value of the object key.
          type: object

means that there's an Object (so a Data.Aeson.Object) with un-spec-ed contents. So we should parse a Data.Aeson.Object there.

It probably is not totally correct to say the specification is wrong. I believe as to JSON Schema the validation would succeed. But it is definitely not complete in the sense that the whole API is discoverable which is a bit a shame.

I think in general it is reasonable to disallow unspecified properties in the generator. But in the case of an empty object I think it is a good solution.

I created an issue in the repo of the code generator: Haskell-OpenAPI-Code-Generator/Haskell-OpenAPI-Client-Code-Generator#18

To be fair, this is too bad. I'll have to do some of my own json parsing on that object to get the right data out in practice, but oh well.

For the generated code to be usable, we'll want to do some of this parsing for the user by writing some code manually. This would mean we'd have some extra module(s) that have been written manually. What do you think?

Yes, this would make using it definitely easier. Ideally, this would be done without touching the generated code but this restricts the solution to creating a parser for the Data.Aeson.Object to a newly created NotificationEventData (or something like this) type which makes the handling easier. Or do you have another proposal? Or would you even change small parts of the generated code?

If you have the time to do this, feel free to add the corresponding code to this module. I have probably too much to do with the generator to be able to add this in the near future.

There is no hurry. I have no better solution either.

The changes to the generator for this issue were implemented in Haskell-OpenAPI-Code-Generator/Haskell-OpenAPI-Client-Code-Generator#20. This issue will be left open until the implementation of the manually written helper code for the NotificationEventData is done.