How should I create a resource as a relationship?


#1

I’ve been googling for hours and read the specs a few times, but I haven’t found a clear answer to my problem.

Let’s say I have users and articles. I want to create an article which will be owned by a user (that already exists). Should I call POST /articles and then call POST /users/id/relationships/articles? This seems weird to me since I know to make two calls and if my app fails between the two, there will be an article without an owner. Also, the database might not allow that anyway.

So obviously a POST call should be made on either /users/id/articles or /users/id/relationships/articles. It makes more sense to me to call POST /users/id/articles since the JSON payload will contain an entire article, not just a resource identifier and from my understanding self links only deal with resource identifiers. But I actually have no idea since the specs aren’t clear on that and there are no examples.

I’ve read about using POST /articles and having the user defined in the author relationship, but I would like to avoid that method if possible. I would prefer to be able to tell if a user is authorized or not to accomplish a certain task by only looking at the URL and not parsing the request’s body.

Thanks in advance


Creating resource with its relations
#2

The way we have done this in our framework is to do something equivalent to POST /users/id/articles. See a sample request and its payload for clarity. We automatically update the backing datastore accordingly based on whether or not the relationship is bidirectional or what have you.

According to the spec, this appears to be legal:

A resource can be created by sending a POST request to a URL that represents a collection of resources.

POST’ing to /users/ID/articles is, in fact, a URL representing a collection. Where we made a judgement call was in the implicit linking of relationships (I’m not sure if JSON API has made a strong ruling on this). In our case, we know that by posting to a specific collection, the collection is somehow owned or related to its parent. Consequently, we implicitly add the relationship from the parent (in our example, this is a bi-directional relationship).

Hope this helps. Comments/thoughts are always welcome if others have found a more appropriate approach.


#3

Yes, this is what I’d recommend as well.


#4

How do you guys generate that payload - do you use ember-data or not?


#5

I believe such a payload can be generated by ember-data. We have a group internally using ember-data with our framework, but I have not tried to do this personally.


#6

Unless I’m missing something it seems it would be simpler to create the article resource under /articles directly and include user as a relationship no? i.e.:

  POST /articles
  {
    data:{
      type:'article',
      attributes:{...},
      relationships:{
        author:{
          data:{
            type:'user',
            id:{id}
          }
        }
      }
    }
  }

#7

@adam yes, but according to the OP:

so this is not the method he is looking for! :slight_smile: