4

I'm designing an web app with React as front-end, and I'm trying to properly understand REST API practices. Reading resources online, one can get the idea that the REST API is seen kind of like an adapter to the database. However, what with "relative" resources? For example the ones related to the current user or the current time.

I'm designing an app that is about learning, it's "relative" concepts, like "current week of the course" are very important.

Would be considered the best practice to have one end-point with all the relative data, like: /api/me.json (so: user id, his active course, current week of the course etc.) , and everything else absolute, like:

  • /api/user/[id]/course/progress.json
  • /api/user/[id]/course/week/[week_id]/progress.json

Or maybe it's ok to have multiple relative resources for example: /api/me/course/progress.json?

Or maybe even: /api/me/course/current_week/progress.json (double relative resource)?

Are there established practices of how to handle such cases?

  • week sounds like a filter to me. /api/user/[id]/course/progress.json?week_id=123 – Robert Harvey Dec 1 '17 at 15:56
  • In any case, once you get beyond ordinary CRUD actions, studying HATEOAS can be quite useful. – Robert Harvey Dec 1 '17 at 15:59
3

Reading resources online, one can get the idea that the REST API is seen kind of like an adapter to the database.

That's true, you can get that idea. It's not quite right. The REST API could be an adapter for any number of different implementations. That's part of why the REST architectural style was so effective; clients and servers are able to collaborate without needing awareness of each other's internals.

Short answer: any of your choices are fine.

The first piece to understand is the concept of resource in the REST architectural style.

The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. 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.

"Current user" and "current week" are perfectly reasonable concepts, so of course they can be resources. "Current week" is just a mapping that evolves relative to a clock, "Current user" is just a mapping to the operator associated with the current request. There are no problems there.

As Ewan notes, REST is stateless -- more precisely, the REST architectural style does not allow you to store client state on the server. The effectively means that the message returned by the server can consider only the server's own state combined with the data provided in the request. Another way of thinking of this: the client's requests are not allowed to use pronouns without including the antecedent.

So assuming that "current user" relates to the client (for instance, the human operator working in the browser), there must be some data in the request that communicates which user we are talking about. That could be information encoded into the resource identifier itself, or it could be included in the metadata of the request (for instance, HTTP has an Authorization header that could carry this data).

Of course, part of the point of "current week" is that it changes; next week is different from last week. Alice and Bob are different "current users". So a certain amount of care needs to be taken with caching; making sure that the server is clearly communicating (via the meta data) who is allowed to read copies of the current representation, and how for how long that representation may be considered valid.

For some caching scenarios, it can be useful to link the response back to a different resource with a "canonical" identifier. /user/alice might be the canonical identifier for /me when Alice's request is being processed; /2017-W48 might be the canonical identifier for /current-week. For various use cases, you might redirect a request to the canonical resource, rather than handling it immediately.

0

One of the key things, arguably THE key thing about REST is 'Stateless'.

This means that you can't just hit /me and have the server know who you are. You have to send that data somehow and the HTTP GET way of doing that is either in the path or the query string.

so

/users?id=myid

or

/users/myid

With the later being the 'cooler'. Similarly with the current date, its best to send the date you want rather than have the server pull the current time from the OS.

eg

/courseProgress?userId=[id]&courseId=[courseId]&date=[utcdatetime]

When you have multiple parameters the url starts to get a bit ugly as it becomes more of a RPC than a Resource.

  • But how client will know his id? He has to receive it from somewhere, and this somewhere has to know who he is. – Luken Dec 1 '17 at 17:12
  • presumably the client has logged in and identified themselves with a username/password or some such? – Ewan Dec 1 '17 at 17:13
  • Yes. Are you aiming at getting id in the response confirming authentication? – Luken Dec 1 '17 at 17:18
  • I think that would be the usual way. perhaps a jwt with the userid as a claim? – Ewan Dec 1 '17 at 17:21
  • Wasn't the use of [id] already established in the question? I thought this was a question about "relative resources." – Robert Harvey Dec 1 '17 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.