beetbox/aura

Simplify relationships

Closed this issue · 6 comments

Currently relationships are as follows:

"relationships": {  
    "albums": [{ data: { type: "album", id: "84" } }]  
}

To me this looks like it could be simplified to:

"relationships": {  
    "albums": [84]  
}

so each key is just a list of ids.

Maybe there's some reason that I'm unaware of, but it seems like there's a lot of 'fluff' for what is essentially a list of integers.

Yo! That's a very good point. The reason it was this way is that we're trying to follow JSON API, which at one point (although it's an evolving standard) recommended this more general/flexible format for all relationships.

It looks like this is still allowed in the current version of the standard, although there are other options such as arbitrary meta values. It's a little disappointing that there's not a way to just simplify this down to a list of IDs, but maybe I'm missing something?

Of course, the JSON API standard is not holy, so if we think there's no good way around it, we could opt out for this specific type of thing.

Right! I forgot about the JSON API thing.
It does make sense to use relationships rather than meta info because that's what they are, and I guess sticking to the JSON API would be good for consistency.
It's not really a problem, just a shame that in this case there's more complexity than needed.
Also this is my first time on the non-consumer side of an API, so probably I don't fully get the benefits of following the JSON API spec

I think one thing that's confusing me is that the JSON API spec is a bit unclear and possibly inconsistent with regards to relationships.

The value of the relationships key MUST be an object (a “relationships object”).
A “relationship object” MUST contain at least one of the following:

  • links
  • data
  • meta

But in this example (and all others I've seen), the relationships key is an object containing relationship objects, not one itself.

"relationships": {
    "author": {
        "links": {
            "self": "http://example.com/articles/1/relationships/author",
            "related": "http://example.com/articles/1/author"
        },
        "data": { "type": "people", "id": "9" }
    },
    "comments": {
        "links": {
            "self": "http://example.com/articles/1/relationships/comments",
            "related": "http://example.com/articles/1/comments"
        },
        "data": [
            { "type": "comments", "id": "5" },
            { "type": "comments", "id": "12" }
        ]
    }
}

I also noticed that the AURA example for relationships does not follow the JSON API examples. At the moment it is

"relationships": {
    "albums": [{ data: { type: "album", id: "84" } }]
}

Whereas following the JSON API examples (and correcting the missing quote marks) it should be (for a single album):

"relationships": {
    "album": {
        "data": { type: "album", id: "84" }
    }
}

Or for multiple albums (maybe this is required?):

"relationships": {
    "albums": {
        "data": [
            { type: "album", id: "84" },
            { type: "album", id: "97" }
        ]
    }
}

Overall I'm a bit confused.

Yeah, that wording is a bit confusing. Reading somewhat carefully, however, it says:

The value of the relationships key MUST be an object (a “relationships object”).

Notice that it says "relationships object," plural? Then it says:

A “relationship object” MUST contain at least one of the following:

and gives that list. (Singular.) So I think it's saying:

  • A "relationships object" maps a name (e.g., author or comments) to a "relationship object" (singular).
  • A "relationship object" actually describes the relationship and must contain links, data, or meta.

Does that resolve the ambiguity?

Oh, but yes, I think you are definitely right about the list at the top level for albums being wrong! (Or from an outdated JSON API spec.) Your corrected version looks right to me.

Can't believe I missed that plural! All makes sense now :-)

I'll do a fix for the outdated bit at some point and send it over. Sticking to JSON API formatting seems sensible to me now.