New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposed Merger of URL and ID Styles #183
Comments
|
+1. But what about allowing arbitrary keys on a |
|
@daliwali I think it would make sense to allow any meta-data fields that are allowed in the top level What meta-data do you have in mind? |
|
@lgebhardt actually disregard that. I had thought it might be possible to expose extra meta-data per link, like if I have a join table with extra columns describing the relation. Then I realized that it wouldn't work given that the format doesn't allow for more than just the IDs per relation. |
|
|
|
Woot! @lgebhardt @dgeb , would you like to submit a patch that fixes this, or should I work on it? I'd like you to get the credit, but I know you may be busy. |
|
@steveklabnik Thanks. I assume you must be busy too. I'm currently taking a whack at a patch. I hope to have a PR soon. |
|
Great! I'll leave you to it then. |
|
One style to rule them all :) {
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": {
"href": "http://example.com/people/{posts.author}",
"type": "people",
"id": "9"
},
"comments": {
"href": "http://example.com/comments/{posts.comments}",
"ids": [ "5", "12", "17", "20" ],
"type": "comments"
}
}
}]
}What exactly do these non-inline templates enable us to do? Just some thoughts. Tell me what you think. |
|
@MajorBreakfast In the case you present there may or may not be a space savings (I haven't counted the characters). However if you are returning a long array of Posts you will see some space savings since the links object can be shortened down to a single id, or an array of ids. You can eliminate the duplicate keys {
"links": {
"posts.author": "http://example.com/people/{posts.author}",
"type": "person"
},
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": "12"
}
}, {
"id": "2",
"title": "The Parley Letter",
"links": {
"author": "12"
}
}, {
"id": "3",
"title": "Dependency Injection is Not a Virtue",
"links": {
"author": "12"
}
}]
}instead of {
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": {
"id": "12",
"href": "http://example.com/people/12",
"type": "person"
}
}
}, {
"id": "2",
"title": "The Parley Letter",
"links": {
"author": {
"id": "12",
"href": "http://example.com/people/12",
"type": "person"
}
}
}, {
"id": "3",
"title": "Dependency Injection is Not a Virtue",
"links": {
"author": {
"id": "12",
"href": "http://example.com/people/12",
"type": "person"
}
}
}]
}In addition to some space savings, I think it also makes the document easier to read. Hope that helps |
|
That makes sense. That's a lot of repetition |
|
If we were to eliminate the |
|
To be clear, I mean: Number,String -> toOne |
|
@MajorBreakfast I'm addressing this in my PR. Here's what I have written about that so far:
|
|
You could add "... wordier than using URL Templates if you return many documents." because that helped me understand it. :) However I now see why we need both. |
Removes ambiguity around the `links` key in documents, which clears path to merge the URL and ID styles of the spec. This is discussed in detail in json-api#183.
|
I'd like to raise a tangenital point while #185 is gaining traction. Once this goes live, we'll have de facto support for to-one polymorphism, but not to-many. With regard to several other issues about polymorphic types, this solution seems to solve the problem for to-one relationships – specifically, I could have a different For to-many relationships, though, we're stuck with: one type per collection per link relation per document. It seems arbitrarily restrictive given the freedom we're now being given in to-one relations. One way we might do this would be, instead of an {
"posts": [
{
"id": "1",
"title": "One Type Purr Author",
"links": {
"authors": [
{
"href": "http://example.com/people/9",
"type": "people"
},
{
"href": "http://example.com/cats/1",
"type": "cats"
}
],
"comments": {
"href": "http://example.com/comments/5,12,17,20",
"type": "comments"
}
}
}
]
}The most obnoxious part about this is that you have to check whether it's an array or an object, but we already have this annoyance with the current (pre-#183) link relations, which expresses to-one or to-many by checking if it's an array or a single id. I'd be open for a better way to do it, too, but wanted to submit a possible solution instead of just quibbling. |
|
@mikelinington It's simple and consistent with the other changes we're proposing. I like it. |
|
Is there a way to make it more brief using templates? Query explicitly using the ids: {
"links": {
"posts.authors[type=people]": { "href": "http://example.com/people/{posts.authors}" },
"posts.authors[type=cats]": { "href": "http://example.com/cats?authorOfPost={posts}" }
},
"posts": [{
"id": "1",
"title": "One Type Purr Author",
"links": {
"authors": [
{ "id": "1", "type": "people" },
{ "id": "1", "type": "cats" }
]
}
}]
}and this would also work because we know the types and thus where to look in the returned compound response: {
"links": {
"posts.authors": { "href": "http://example.com/posts/{posts}/authors" }
}
} |
Initially proposed in [a comment][ac] within json-api#183, this expands the to-many relationship format to accomodate an array of `link` objects. [ac]: json-api#183 (comment)
Initially proposed in [a comment][ac] within json-api#183, this expands the to-many relationship format to accomodate an array of `link` objects. [ac]: json-api#183 (comment)
|
Closing now that 8d3adde has been merged and @mikelinington's suggestion has been captured in #187. @MajorBreakfast would you mind repeating your comment about templates in #187? I don't want to lose your suggestion and that issue is more focused than the discussion here. |
@dgeb and I are working on tools to generate client and server implementations of JSON API and have been tripped up by incompatibilities in the URL and ID styles.
We'd like to propose a merger of these two styles so that they can co-exist in the same spec without conflict. This proposal slightly modifies the way links and related IDs are handled.
Current Spec
Currently the same keys can be used for either IDs or URLs for a document's
linkswith no indication of what type of data the key contains:or
Problems with the Current Spec
Using the same keys to store either IDs or URLs creates confusion for producers and consumers of the spec (as shown by the number of issues here related to IDs and links). Given that not all IDs are going to be integer numbers (UUIDs in particular, but there are other key systems in use, some of which may have a passing resemblance to urls), it is non trivial to programmatically determine whether an ID or a URL was provided by an API in a general way.
Using the same keys to store either IDs or URLs in the current manner also precludes the option of providing both IDs and URLs. If related documents are specified by URLs in the primary document and included as linked documents in a compound document, then there is no path to get from a primary document to its included linked documents. For example, a client would not be able to easily determine which comments go with which post in the following example:
Furthermore, if a document's link can only be an ID or URL, there is no way to specify a TYPE without requiring use of the top level
links.Proposed Changes
I propose we remove the ambiguity around the
linkskey in documents by requiring that an attribute in a document'slinksbe one of the following:id,hrefandtypeDefault to IDs
In this example, an API consumer can assume that authors and comments are IDs:
However, this is no longer a valid representation of URLs:
Support URLs and TYPEs with Link Objects
To handle URLs we will allow each attribute of
linksto contain a "link object", which can contain any or all of the following attributes:href,idandtype. This is discussed in #164.Simple URL
To return URLs we use a link object and the
hrefattribute. For example:Support for Types
We can add a TYPE like this:
Also support IDs
We can also add IDs for fully defined links, like this:
IDs with Types
Finally, we can use the TYPE with only IDs if necessary:
There is now no ambiguity between what's an ID and what's a URL.
Less Wordy IDs and URLs together - Templates to the Rescue
Since links can also be defined with URL Templates we still have the opportunity for (relatively) concise responses.
This allows IDs to be converted to URLs using the URL Template Shorthands, such as:
Because the top level
linkskey is not repeated we can keep the response more concise, while still providing both IDs and URLs to the client. It's then up to the client to decide how best to access these.Benefits
Please let me know what you think. If approved, @dgeb and I will be glad to put together a PR and close out all related issues.
The text was updated successfully, but these errors were encountered: