Skip to content
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

Why is (id,type) tuple a unique identifier? #373

Closed
mehaase opened this issue Feb 26, 2015 · 5 comments
Closed

Why is (id,type) tuple a unique identifier? #373

mehaase opened this issue Feb 26, 2015 · 5 comments

Comments

@mehaase
Copy link

mehaase commented Feb 26, 2015

I'm interested in json:api for a RESTful API that I'm starting to work on. I sat down to start digging into the details. I was surprised almost at the outset by this requirement:

A resource object MUST contain at least the following top-level members:

  • "id"
  • "type"

Later...

A resource object's type and id pair MUST refer to a single, unique resource.

And...

A resource object MAY include a URL in its links object, keyed by "self", that identifies the resource represented by the resource object.

Given that a resource's URL already uniquely identifies that resource, what is the design rationale for requiring a unique (id, type) tuple instead? Why not make the self URL mandatory? Then you would have a unique identifier, and this would allow RESTful APIs for resources that don't necessarily have a distinct ID.

I'll offer an example. I have an authentication API with the URL /api/authentication. A client can POST a username and password to this resource. If the username and password are valid, the API returns a resource representation that includes an API token for the client to use with future requests. I can dream up a "type" for this resource but I really don't have any good ID for it, because it's a singleton resource.

Feedback? Am I doing it wrong?

json:api is the first standard I'm looking at, but at a glance I don't think JSON-LD or HAL require this same (id, type) identifier. The json:api FAQ doesn't explain this design decision and I can't find any other issues related to this design, so apologies if I'm asking an obvious question. Thanks.

@bintoro
Copy link
Contributor

bintoro commented Feb 26, 2015

This issue seems to pop up repeatedly (recently in #354), and I'm about to submit a PR that clears it up in the spec.

My interpretation is that there's no way you can equate HTTP resources and JSON API resources. The choice of the word "resource" in JSON API is kinda unfortunate, but it may be too late to change that.

In HTTP, a resource refers to the entirety of the thing(s) affected by a request, hence they can be uniquely identified by a URI. JSON API resources, in turn, are the underlying things that HTTP resources provide an interface to. To put it another way, HTTP resources can be represented by JSON API resources.

From Fielding's dissertation:

A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.

The way I see it, JSON API resources are those entities. They are just objects with attributes and relationships.

A URI like http://example.com/people/1 might be a one-to-one mapping between an HTTP resource and a JSON API resource. But the very same JSON API resource may be exposed via any number of other HTTP resources as well; for instance, at http://example.com/articles/1/author or as part of a collection at http://example.com/people.

@dgeb, before I submit the PR, do you generally agree with my interpretation or shall we attempt to align the two notions of "resource" more closely?

@mehaase, as for your specific scenario, I would suggest representing the state of the authentication service as a JSON API resource that simply gets a UUID as its ID. The client is free to discard the ID, and the server is under no obligation to accept a request that tries to reference an existing ID if such an operation doesn't make sense. The service may be a singleton but its representations are not.

@dgeb
Copy link
Member

dgeb commented Feb 26, 2015

@mehaase I agree with @bintoro that "the service may be a singleton but its representations are not." There could be value for both servers and clients in providing an ID for each authentication instance, which is what's being returned from your authentication service.

With that said, we should provide a rationale in the FAQ page for the type / ID requirement. One reason for this requirement is that it allows for compound documents that include linkages between resources. It also forms the basis of all of our URL recommendations.

@bintoro I would like to hear from @steveklabnik about our usage of the term "resource" and the best way to explain and/or make it more correct. I wonder if #363 could provide the answer to clarify a lot of terminology in one place.

@steveklabnik
Copy link
Contributor

One of JSON API's key principles is compromise between the REST faithful (of which I count myself) and people who haven't actually read the thesis.

"Resource" is a prime example of this. We use the common usage of "resource" rather than the thesis version. Our "resources" would be "entities" according to Fielding.

We could change our terminology to be more accurate from Fielding's perspective, but then we risk lack of adoption. One of the reasons that those other specs have not caught on as much as they could have is that their target audience doesn't understand their words.

I don't think this is a bad thing. It's a tradeoff, like any other technical decision.

@mehaase
Copy link
Author

mehaase commented Feb 26, 2015

Ah, okay. That all makes sense now. Thank you for the overview as well as the feedback on my specific case.

@mehaase mehaase closed this as completed Feb 26, 2015
@bintoro
Copy link
Contributor

bintoro commented Feb 26, 2015

With that said, we should provide a rationale in the FAQ page for the type / ID requirement. One reason for this requirement is that it allows for compound documents that include linkages between resources.

B-but... I suppose you could do that with URIs, too.

The fundamental reason is that JSON API wants to provide a kind of object model — the "entity" layer. You need dedicated IDs for that.

Incidentally, this is the major difference between HAL and JSON API. HAL only deals with true HTTP resources and lacks the entity part.

I much prefer the JSON API approach, as it's more flexible. You can implement one-to-one correspondence between resources and HTTP resources à la HAL, but if you want the objects too, you already have a scheme to represent them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants