Important note
The focus of this question is on API endpoints that differentiate which resources are returned depending who authenticates, e.g. Alice gets resource A and B returned, and Bob gets resource X and Y.
It is NOT about differentiating the representation of resources returned.
All the endpoints return JSON representations of resources.
Preface
Please consider the following three potential API endpoint designs, all returning thing
resources of a user.
Endpoint A
GET /things
If authentication credentials for <user_x>
are provided with the request, it returns thing
resources that specifically relate to <user_x>
.
For example, authenticating user Alice gets resource A and B returned, and authenticating user Bob gets resource X and Y.
So the differentiation of the response for different authenticating users is on which resource instances are returned and NOT on what information of these instances is returned (i.e. the resource representation).
When authentication fails a 401 response is returned.
Endpoint B
GET /user/<user_x>/things
Endpoint C
GET /things/?user_id=<user_x>
Both endpoint B and C provide the thing
resource instances related to <user_x>
, iff the authenticating user has the right to access these thing
resources.
The representation of the thing
resource instances returned, e.g. what information about the resources is returned, can vary depending which user authenticates. For instance, <user_x>
or an admin user might get back richer data per resource instance then a user with limited access rights.
Authenticating users that don't have any access rights to thing
resources of <user_x>
will get a 401 response.
My questions
I would like to have answers to the following questions:
1) Is Endpoint A RESTful?
2) Does Endpoint A have a good URI design?
3) Are Endpoints B and C RESTful?
4) Do Endpoints B and C have a good URI design?
I'm looking forward to your answers. I also provided my own answers below and would be grateful for feedback on that as well.
Thank you!
— Freddy Snijder
An API endpoint is a point at which an API -- the code that allows two software programs to communicate with each other -- connects with the software program. APIs work by sending requests for information from a web application or web server and receiving a response.
A RESTful web service request contains: An Endpoint URL. An application implementing a RESTful API will define one or more URL endpoints with a domain, port, path, and/or query string — for example, https://mydomain/user/123?format=json . The HTTP method.
Each resource in REST architecture is identified by its URI (Uniform Resource Identifier). A URI is of the following format − <protocol>://<service-name>/<ResourceType>/<ResourceID> Purpose of an URI is to locate a resource(s) on the server hosting the web service.
UPDATED 18 March 2015 13:05 CET to include feedback in the comments of the question and answers given.
RESTfulness
From a purist point of view non of the endpoints are RESTful. For instance, the question doesn't state if the responses contain links to the resources such that the client can retrieve the resources without needing knowledge about how the URIs to the resources are constructed. In fact, as pointed out in this blogpost, almost no API defined in practice, other then the World Wide Web itself, can be considered RESTful.
So is there nothing useful to say about these endpoints? I think there is. We can talk about statelessness and idem-potency of processing the endpoints, which is important to scalability. And we can talk about safety of endpoints which is important to security.
For all endpoints you could state the following:
Is it stateless?
Yes, user authentication credentials are a part of the application state and are send with every request, thus everything the server needs to know to handle the request, without keeping state, is in the request. (The complete state is transferred)
Since these endpoints process GET requests, are they idem potent?
Endpoint A) : Yes, because the request to endpoint A, including the user authentication credentials, should be considered as a whole: no matter how often you repeat the same request, with the same credentials, you will always get the thing
resources for the authenticating user.
However, If you only consider the URI, the request is actually not idem potent, because the response changes depending on the credentials provided.
Endpoint B) and C) : Similar to A), you will always get the thing
resources of <user_x>
provided in the URI, no matter how often your repeat it.
On top of that the requests are also idem potent only considering the URI itself, everything you need to know about the request is in the URI, the user credentials can only change the representation of the returned thing
resources, not which resources are returned.
Since these endpoints process GET requests, are they safe?
Yes, because the request does not alter any data and does not have any other side effect.
URI design
Although from a purist REST perspective URI design is considered irrelevant, in a practical situation where software developers and API end-users use and deal with the URI design is relevant.
Does Endpoint A have a good URI design?
Yes and No. When this URI is hidden from an application user, and this will not be bookmarked or shared this design is fine. However, when this URI is exposed to end-users this URI is not designed well because when sharing this as a link the recipient won't see the same data unless she authenticates as the same user.
Do Endpoints B and C have a good URI design?
Yes, the end-user can understand semantically what the endpoint is about and the URIs are sharable between users.
So, instead of defining all three end points you could chose to only define endpoints B and C because they can provide everything what endpoint A could provide, plus it is obvious from the URL what is requested.
Please let me know what you think. Thank you!
— Freddy Snijder
This is a very good question and the exact question I had been asking myself while currently developing an API for a project I am working on. I am relatively new to REST so are going through a steep learning curve and are therefore far from being an expert!
I have been reading the "RESTful Web Services Cookbook" by Subbu Allalaraju.
For what it is worth these are my thoughts, they are very similar to the answer you have provided yourself. In practice, I am sure that it is a common scenario that the authentication credentials impact on the information returned for the same URI. The credentials are effectively just another query parameter.
1) Is Endpoint A RESTful?
Yes, it is stateless as the authentication credentials are passed from the client with the request.
It is idempotent as per https://www.w3.org/Protocols/HTTP/1.0/spec.html section 10.2 Authorization "Responses to requests containing an Authorization field are not cachable." so the same credentials will always retrieve the same result (the authenticating user's list of things).
2) Does Endpoint A have a good URI design?
No, it is effectively the same as Endpoint B or C where the user makes a request to retrieve their own things, but with less flexibility and clarity.
3) Are Endpoints B and C RESTful?
Yes, they are stateless and idempotent.
4) Do Endpoints B and C have a good URI design?
Yes, I think either may be a valid design. There are endless discussions on the pros and cons of each approach!
I have chosen to go with something similar in my own API.
GET /user/01/things (authenticating correctly as user 01)
Response 200 OK: Yes user 01 of course you can see your own things.
GET /user/01/things (authenticating correctly as user 02)
Response 200 OK: Yes user 02 you are a superuser and can see what things user 01 has (or perhaps a subset of them).
GET /user/01/things (authenticating correctly as user 03)
Response 403 Forbidden: No user 03 even though you have authenticated correctly you are just a general user and cannot see what things user 01 has. Or you could return Response 200 OK and include similar information in the response data, it all comes down to how you design your API and how much information you need to be able to pass back in this situation, I think either approach is valid.
GET /user/01/things (authenticating incorrectly as user 01)
Response 401 Unauthorized:
List of HTTP status codes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With