graphiti-api/spraypaint.js

Sideposting verbs do not seem to comply with JSONAPI specification

jlandic opened this issue · 4 comments

Hi,

When attempting to persist relationships, the addition of the HTTP verb in the method field of the relationship's data payload may not be strictly JSONAPI-compliant.

As per the specification:

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

id
type
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.

In addition, a resource object MAY contain any of these top-level members:

attributes: an attributes object representing some of the resource’s data.
relationships: a relationships object describing relationships between the resource and other JSON:API resources.
links: a links object containing links related to the resource.
meta: a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.

This additional field provokes errors in some server-side implementations, as a non-valid data representation.

Would there be a way to deal with sideposting in another fashion? Or allow the developer to choose whether or not to enable this "Graphiti-only" behaviour?

Hi @jlandic and @vitorreis !

We put the method alongside the Resource Identifier in the relationships payload.

“resource identifier object” MUST contain type and id members.

A “resource identifier object” MAY also include a meta member, whose value is a meta object that contains non-standard meta-information.

This doesn't seem to disallow an additional optional key of method. We've talked to the JSON:API guys and I think sideposting will eventually get into the spec in some form. I haven't heard it brought up as a backwards-incompatibility.

I hear you that some server-side implementations would reject this. JSON:API doesn't have this functionality (persist a graph of objects in a single request). So basically if you aren't using Graphiti server-side, then you aren't able to use this feature - because this feature isn't available in any JSON:API server implementation except for Graphiti.

We might be able to improve the picture of saving relationships to /relationships URLs, which would require a separate request. This is not needed in Graphiti with sideposting, and I view these as the worst part of JSON:API, but may be needed (or at least helpful) for other server-side implementations.

Does all that make sense?

Hi @richmolj !

Thanks for your answer. It does indeed make sense to me. I reckon the server-side implementation has no reason to reject such a resource identifier in the end, so I guess it's worth a discussion with their maintainers. In the mean time I'll monkey-patch the request server-side to remove the key.

However, regarding this rule:

A “resource identifier object” MAY also include a meta member, whose value is a meta object that contains non-standard meta-information.

If I understand correctly, it might be preferable to nest the method key inside a meta object, like so:

{
  "id": "1",
  "types": "resources",
  "meta": {
    "method": "update"
  }
}

What do you think?

This is a problem when using Spraypaint with http://jsonapi-resources.com on the backend as well, the request gets rejected because of the unknown key. I ended up using Hashie DeepLocate to remove the method parameter in a before_action to get things working.