19
8
|
I'm currently designing a REST Http api. (With HATEOAS stuff, to make clients "simpler", and avoid clients to do complicated things, instead of letting the api tell them what to do ...)
Because of the social characteristic of the app, in order to interact with the application, users need to be authenticated, and each user will have a slighty different "view" of the data. We'll take twitter as an example, it will be easier for everyone.
To authenticate users, we'll use OAuth, easy.
So, in the client (ios app...), a random user would maybe seeing a list of users should see:
And another user would maybe see:
To achieve this, the first solution would be for the client (in oauth term, the iphone/web/etc app), to get a list of all the users the authenticated user follow, and each time the client displays a list, compare each user with the list of followed users to know if it should display "Not Following" or "Following".
The requests/responses would be:
and
This seems to be quite, stateless. Good.
Now what if i want to make client developers life easier, and embed directly in the user list response, the relationship of each user, relative to the authenticated user:
So, questions:
| |||
add comment |
9
+100
|
You should definitely embed the relationship in the user list response. It would be bad practice to force the clients calculate it.
This does not break the stateless contraint of REST as it's the interactions that are stateless, not the systems. The server will almost always have to store and maintain state. For instance the server will need to maintain state of who is following who.
Finally, I think you are not fully getting the "State" part of Hypermedia As The Engine Of ApplicationState. Basically, the resources are state machines. When you
GET a resource, the valid state transitions are presented has hypermedia controls (links and forms) in the response. It's by following these links and submitting the forms that the client can change the state of these resources. | |||
add comment |
7
|
Including the description of the relationship type in the response body is not breaking the stateless constraint. The stateless constraint means that the web server can respond to the request without being dependent on any previous request (as has been mentioned by Tom, Jacob and kgb).
I'm not qualified to say whether what you're doing is a "best practice" or not, but in general Roy gave the following reasons for and against making your API stateless (see section 5.1.3 of his dissertation). Like many things in life there is a trade-off:
Problems with a Stateless System
Benefits of a Stateless System
RESTful Resources
Also, according to Roy's definition of a resource I'd take issue with how I think you're defining your resources, with each user getting a slighty different "view" of the data. Roy defines a resource as a membership function that varies over time (see section 5.2.1.1 in the dissertation). The user list resource you've defined above varies by both time and by the Authorization header. Two different clients requesting /users at the same time would most likely end up with completely different results.
EDIT: Using the HTTP vary header would allow it to be cached.
| |||
add comment |
3
|
If you think adding "relationship" property to users breaking stateless constraint, then adding it when "/following" is in the request, would be breaking it too.
I would say "stateless" means no response depends from the other requests/responses.
HTTP is a stateless protocol, but it can store quite a lot of data about the user in the request/response headers(and i am not talking about sessions/cookies)
| ||
add comment |
2
|
From Roy Fieldings Architectural Styles and the Design of Network-based Software Architectures:
So you embedding entity data directly in the response does not make your solution non-stateless.
On good practice:
It's a lot better to actually serve the user data than a list of numbers for the client to figure out what to do with.
However, depending on the amount of data for each user, you could consider giving a list of links to the user resource and state the "follow" relation as well. Then the client can fetch the details on the needed users. Which solution you choose should depend on what you believe the client will be needing, you might end up using several approaches.
| ||||
|
1
|
I don't see the correlation between embedding the "relationship" information into the
/users resource and the stateless constraint. So I see no issue.
However, I would argue you are breaking the "identification of resources" constraint.
/Users for you and /Users for me is going to show a completely different set of relationships. I would argue those are two different resources and therefore should have distinct URIs.
There are some scenarios where you can change a representation based on who the user is (for security reasons for example) but this case is just too much change for my liking.
| ||||||||
|