mattpolzin / JSONAPI

Swift Codable JSON:API framework
MIT License
75 stars 19 forks source link

"data" key inside relationships is not guaranteed. How do I make them optional? #106

Closed reshadf closed 1 year ago

reshadf commented 1 year ago

I have a json returned from the server where the "data" key inside the relations is not always present if the relation is missing. Therefore It fails with decoding because in this case "administration" has no data key. Is there a way to work around this? I tried making the entire relationship optional but that doesn't work. @mattpolzin ( if it has a data key or the entire "administration" block is committed it works as expected )

Thank you for your time in advance!

        "administration": {
          "links": {}
        },
        "costCenter": {
          "links": {},
          "data": null
        },
mattpolzin commented 1 year ago

I had to look this one up but unfortunately the library does not currently support exactly what you are describing. On one hand, support could be added for this situation. On the other hand, the relationship object you are describing is not technically compliant with JSON:API. The specification requires that at least one of data, meta, and links are present in a "relationship object" and it requires that the links contain at least one of self, related, or an extension-defined link.

That is, the specification only appears to intend that a relationship object represent the absence of a relationship by (a) omitting the relationship object entirely or (b) providing a null data entity within the relationship object. Providing links or meta seem to be ways of describing the relationship, not omitting it.

Is it possible for you work with the provider of this API to update the responses to provide a null data entry or omit the relationship object entirely? If so, one of the relationship types this library currently supports would work for you. I know that asking for an API fix is not the desirable result of this question.

There are a few ways the library supports not providing the id/type of a relationship -- based on your original message, I think you are already familiar with these options, but I'll list them out for the sake of a complete answer:

When the entire relationship object may not be present

ToOneRelationship<Widget, NoIdMetadata, NoMetadata, NoLinks>?

Note that the question mark is at the end of the whole type. This works for a ToManyRelationship as well.

When the data within the relationship may be null

ToOneRelationship<Widget?, NoIdMetadata, NoMetadata, NoLinks>

Note that the question mark is on Widget. This works for a ToManyRelationship as well.

When the data is never expected to be there but meta or links are expected

MetaRelationship<WidgetMeta, NoLinks>

Note that you can make this omittable with a question mark at the end of the whole type.

reshadf commented 1 year ago

Thanks this helps a lot. I will try and see if we can fix it in the api