trailblazer / roar

Parse and render REST API documents using representers.

Home Page:http://www.trailblazer.to/gems/roar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[JSON-API] Relationship links

franzliedke opened this issue · comments

As can be seen in the first example on jsonapi.org, the "links" defined for a relationship are not to be mistaken with the links for a resource.

Thus, relationships defined like the following (taken from the Roar tests), should only add the links to either the relationship or the included resource itself:

has_one :author, class: Author, populator: ::Representable::FindOrInstantiate do
  type :authors

  property :id
  property :email
  link(:self) { "http://authors/#{represented.id}" }
end

In addition, when no link is defined for a relationship, the :relationships key will still contain an element called :links, which is set to nil - it simply shouldn't exist. I was trying to fix this issue, when I encountered the behavior that I reported above.

I am seriously thinking about roar-jsonapi as a separate gem, because I personally do not want to support this convoluted format. I have worked on it for several months now and I still don't understand all it's implicit conditions, which is not appreciated and which is definitely not a good sign for a simple, easy-to-understand media format.

Links in has_one will be rendered in both "sections" (I don't even know the name for all their 523145 different fragment types). We either have to provide an option to say "this link is only meant for relationships or for the included thing".

Or two different property methods to indicate whether you're declaring a included or a relationship fragment.

As for the nil problem, can you please add a test?

I'm dealing with a very similar ambiguity. I need to be able to declare a relationship from resource A to B without the JSONAPI body for resource type A from including the represented form of resource B in the serialized relationships object. I want the much simpler:

{
  "data": {
    "relationships": {
      "Bs": {
        "links": {
          "related": "scheme://host/As/.../Bs"
        }
      }
    }
    "type": "A",
    "attributes": { ... },
  }
}

Changing Document#render_relationships to omit items if they lack type and/or id achieves my goal for the output. However, I would like to avoid having the underlying accessor method called at all because in some cases the accessor is expensive to call (fetches remote data).

@dvogel This is all easily solvable by maintaining two different representer implementation for the two different fragments. Internally, this is how it's implemented already, so we just have to come up with a sensitive API/DSL to tell Roar that.

The main problem is that I don't use JSON API and I have no insight on what is needed and how this ridiculous media format is supposed to work.

@apotonick Submitted my test and fix in #178.

So this fixes the nil link, but we still need to sort out how to say "in has_one, this goes into the included, this goes into the relationships part", right?

Indeed. If you don't come up with anything by then, I'll make a suggestion after the holidays. Cheers and merry christmas! :)

"No pressure, Nick!" 😬