jsonapi-rb / jsonapi-deserializable

Conveniently deserialize JSON API payloads into custom hashes.
http://jsonapi-rb.org
MIT License
26 stars 20 forks source link

Deserializing a Resource Object/Relationship on create throws an error when no ID is provided #21

Open hugofloss opened 6 years ago

hugofloss commented 6 years ago

I'm trying to create a new resource with an existing template relationship and an address relationship that should become a new resource. Example POST request:

{
  "data": {
    "type": "post",
    "attributes": {
      "title": "foo"
    },
    "relationships": {
      "template": {
        "data": {
          "type": "templates",
          "id": "1"
        }
      },
      "address": {
        "data": {
          "type": "addresses",
          "first_name": "John",
          "last_name": "Doe"
        }
      }
    }
  }
}

Because the address relationship does not contain an ID, it throws the following error:

A resource identifier object MUST contain ['id', 'type'] members.

I get that, because the JSON:API documentation clearly states:

A resource object MUST contain at least the following top-level members:
- id
- type

However, the documentation contains an important exception:

Exception: The id member is not required when the resource object originates at the client and represents a new resource to be created on the server.

That's exactly what I'm doing. Can we create an exception for this, or is this is incorrect way?

heberuriegas commented 6 years ago

Any workaround on this?

nruth commented 6 years ago

I think this would need handling in jsonapi-parser e.g.

That said, I don't think you can create the related object like that in json-api.

Batching / multiple creations at once seems to be work-in-progress for the spec: https://github.com/json-api/json-api/pull/1254 https://github.com/json-api/json-api/pull/1197

So you'll want to work around that somehow by going off-spec. That doesn't help with this lib but it makes it less likely to get "fixed" here.

Regarding terminology and the creation optional ID thing, the error message is talking about "resource identifier objects", so let's see what those are.

http://jsonapi.org/format/#document-resource-identifier-objects says it needs id and type and doesn't have any get-outs for creation.

So what does permit creation without an ID? http://jsonapi.org/format/#document-resource-objects talks about the client being able to request the server create the resource and fill in the id.

You've got attributes for a new record in the relationship data. What goes in there? Looking at the spec for relationships, then click on "resource identifier objects" you're back at the original statement of id and type being required.

So while perfectly sensible to want to create them together, it looks like you'll need to create one then the other, 2 requests, or modify your api endpoint to take attributes for the other models and create them on the side, so putting them in the "post" payload instead of in the related address model without an id.