POSTing related data

What is the proper way to handle posting related data that has a Foreign Key constraint. For example, posting a comment to an article.

Would the proper way be:

/article/id/comment
POST /comments
{
data:{
type:‘comments’,
attributes:{…}
}
}

or

POST /comments
{
data: {
type: 'comments’
attributes: { … },
relationships: {
article: {
data: {
type: 'articles’
id: 1
}
}
}
}
}

Let me clarify that the article_id is required on the comment table, so it must be with one call. From what I’ve read, it seems this would be a two step call. First create the comment and then update the article with the comment. That doesn’t work in my scenario due to the Foreign Key constraint. Hope that helps.

I did see the following posted by Michael Hibay in Github (Post by Michael), but still not sure what is the correct way of handling.

There’s been several posts, but it is still unclear to me what is the right way to handle this type of situation

Thank you for any help.

1 Like

I’m warming up to the nested doc on the virtue that the posted JSON more fully describes your action and there are less endpoints. There’s also no in-spec way to say that a given endpoint supports POST. You specify that it is linked, but that only tells you the URL for a GET request. Whether you support POST or not is not able to be specified.

There is a precedent for nested resources (see below). Keep in mind though, that Laravel has removed nested resources from it’s docs.

https://laravel.com/docs/5.1/controllers#restful-resource-controllers
http://guides.rubyonrails.org/routing.html#nested-resources

Your point is well understood, and two network trips is really not good for any solution.

As I described in the other thread, there are currently two approaches to create a resource and relationship in one call. You can post to the relationship link in the spec examples this is listed as:

POST /article/1/relationships/comments
{
  "data":{
    "id": "45d332c0-d2ab-4c66-ae70-b85fd38dfc64",
    "type": "comments"
  },
  "included":[
    {
      "id": "45d332c0-d2ab-4c66-ae70-b85fd38dfc64",
      "type": "comments",
      "attributes": { ... },
      "relationships":{
        "article": {
          "data": {
            "type": "articles",
            "id": 1
          }
        }, ...
      }
    }
  ]
}

Or you can use what @derrekbertrand and I were referring to as the back reference approach.

POST /comments
{
  "data": {
    "type": "comments",
    "attributes": { ... },
    "relationships": {
      "article": {
        "data": {
          "type": "articles",
          "id": 1
        }
      }, ...
    }
  }
}

Two things to point out:

  1. If using the single call relationships link approach, per spec you need to use a UUID for the ID field. However the value does not need to be persisted, and can be treated as an ephemeral document identifier only for the time it was required to provide the linking within the JSONAPI document.

  2. The first example concisely shows you very clearly how redundant and unnecessary the path driven resource hierarchy model method is in practice. The entire path is required as part of the document itself for linking purposes, which obviously means the path is the redundant component which only adds to the collection of reasons not to use it.

A final note here, while strictly speaking the article relationship in the first example is not required. It shouldn’t cause any error to specify the full relationship path in the document. It also has the added benefit of demonstrating how the path hierarchy driven resource structure can be easily replaced within the JSONAPI document.

Glad to see you’re coming around! :smiley:

The ruby reference is more of the inspiration and cause for policy in both the examples convention than precedent. That is because JSONAPI was written with Yahuda Katz who is also the co-creator of Ember.js which I believe came from the RoR world.

More generally the nested resources style is more of a forced compromise than a true solution, due to the inability to adequately describe relationships and types through the URL alone. The true solution, is and has always been hypermedia.

2 Likes

Derrek & Michael, perfect!!! Thank you very much.

One more question regarding both of the examples. It is allowed by the spec to send two new comments at the same time in a POST?

If so, can you post an example of what that would look like? Very much appreciated.

Please see this response to a nearly identical question and follow all the links.

Thank you. Gives me a better understanding of what I can do. Very much appreciated.

have you send the leeter for the your boos
and ask about how to get information for expert my iron