REST API: How to name a derived resource? - api

There is a gazillion of questions about RESTful interface naming conventions, esp. around singular vs plural resource names. A somewhat convention is:
GET /users Retrieve collection of users
GET /users/{id} Retrieve user
POST /users Create user
PUT /users/{id} Update user
DELETE /users/{id} Delete user
However, the above does not work when resource is a value derived from the environment.
My hypothetical application has the following endpoint:
GET /source Get information about the source of the query.
That responds with:
Referrer URL
Remote IP
Since source is derived from the environment, there is never more than one source, therefore calling the resource sources or providing sources/{foo} lookup is not practical.
Does REST style propose how to handle naming of these entities?

Dr. Fielding notes in section 6.2.1 of his famous dissertation :
..authors need an identifier that closely matches the semantics they
intend by a hypermedia reference, allowing the reference to remain
static even though the result of accessing that reference may change
over time.
Therefore, it makes sense to use plain source endpoint.
It would be a different thing if you wanted to provide more general service around IP address provided, like this one.

Related

What's the correct way to create an endpoint in a API REST

I'm drawing my API routes.
A user has projects, projects have actors, actors have addresses.
There is no address without an actor, there is no actor without a project, and there is no project without a user.
Would this be the correct way to build the end_point?
GET /users/{user_id}/projects/{project_id}/actors/{actor_id}/addresses
There is no such thing as a REST endpoint. There are resources. -- Fielding, 2018
What you seem to be asking about here is how to design the identifier for your resource.
REST doesn't care what spelling conventions you use for your resource identifiers, so long as they satisfy the production rules described by RFC 3986.
Identifiers that load data into the query part are convenient if you are expecting to leverage HTML forms:
GET /addresses?user={user_id}&project={project_id}&actor=actor_id
But that design is not particularly convenient if you are expecting to use dot segments to reference other resources.
Choosing some alternative that is described by a URI Template will make some things easier down the road.
/users/{user_id}/projects/{project_id}/actors/{actor_id}/addresses
That's fine. Other spellings would also be fine (hint: URL shorteners work).
Broadly, you choose identifier spellings by thinking about the different contexts in which a human being has to look at the URI (documentation for your API, browser histories, access logs, etc.) and choose a spelling that works well in at least one of those settings.

URIs in REST API endpoints according to Restful practices

I am planning to have these endpoints for our REST APIs.
PUT /tenant/:tenantId/users/save/:username
POST /tenant/:tenantId/users/invite
GET /tenant/:tenantId/users/fetch
GET /tenant/:tenantId/users/fetch/:username
PATCH /tenant/:tenantId/users/activate/:username
POST /tenant/:tenantId/groups/save/
Verbs such as save/fetch/activate are from the consistency point of view. Are these RESTFul according to the REST principles? How should these be changed if at all? Any recommendations?
According to this REST Resource Naming Guide:
RESTful URI should refer to a resource that is a thing (noun) instead of referring to an action (verb) because nouns have properties which verbs do not have – similar to resources have attributes.
And also
URIs should not be used to indicate that a CRUD function is performed. URIs should be used to uniquely identify resources and not any action upon them. HTTP request methods should be used to indicate which CRUD function is performed.
So let's take your first URI as example
PUT /tenant/:tenantId/users/save/:username
Here you are using the verb save. As mentioned before you should not be indicating a CRUD operation in the URI, in this case using a POST would be more appropriate.Here is a guide with the purpose of each HTTP verb. Knowing this, I think that for example a more appropriate URI for that case would be something like
POST /tenants/:tenantId/users/:username
In this cases:
GET /tenant/:tenantId/users/fetch
GET /tenant/:tenantId/users/fetch/:username
you should remove the fetch because you are already telling through the GET verb that data is being fetched. Same goes for the 6th example.
But, this doesn't mean that you can't use verbs in your URIs, in fact there is a specific category called controller which as mentioned in the same guide:
A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.
Use “verb” to denote controller archetype.
This controllers resources could go well (I asume) with for example your
GET /tenant/:tenantId/users/activate/:username.
But I would think that the verb activate should go last:
GET /tenant/:tenantId/users/:username/activate
First note: REST doesn't care what spelling conventions you use for your resource identifiers. Once you figure out the right resources, you can choose any identifiers for them that you like (so long as those identifiers are consistent with the production rules defined in RFC 3986).
"Any information that can be named can be a resource" (Fielding, 2000), but its probably most useful to think about resources as abstractions of documents. We use HTTP as an application protocol whose application domain is the transfer of documents over a network.
GET
This is the method we use to retrieve a document
PATCH
PUT
POST
These methods all indicate requests to edit a document (specifically, to edit the request target).
PUT and PATCH are each ask the server to make its copy of a document look like the client's local copy. Imagine loading a web page into an editor, making changes, and then "saving" those changes back to the server.
POST is less specific; "here's a document that we created by filling in a web form, edit yourself appropriately". It is okay to use POST: after all, the web was catastrophically successful and we're still using POST in our form submissions.
The useful work is a side effect of these edits.
Are these RESTFul according to the REST principles?
Do they work like a web site? If they work like a web site: meaning you follow links, and send information to the server by submitting forms, or editing the webpages and submitting your changes to the server, then it is REST.
A trick though: it is normal in REST that a single method + request uri might have different useful side effects. We can have several different HTML forms that all share the same Form.action. Uploading changes to an order document might have very different effects if the edits are to the shipping address vs to the billing information or the order items.
Normal doesn't mean obligatory - if you prefer a resource model where each form request goes to a specific resource, that can be OK too. You get simpler semantics, but you support more resources, which can make caching trickier.

REST HATEOAS: How to know what to POST?

I still don't understand how the client knows what data to POST when creating a resource. Most tutorials/articles omit this and in their examples, a client always seems to know a priori what to post (i.e. using out-of-band information). Like in this example, the consumer knows that he has to place the order by setting what <drink\> he wants.
I can only image a few approaches and I don't know if they are valid:
1. Returning an empty resource
The client discovers a link to /resource with a link to /resource/create and relation "create". A GET to /resource/create returns an empty resource (all attributes are empty) and a link to /resource/create with relation "post". The client then sets values to all attributes and POSTs this to /resource/create which returns a 201 (Created). This means that the CRUD operations are not located at the resource endpoint but to URI like /resource/create and that the client might set attributes the server ignores (like a creation date which is set on the server side)
2. Returning a form
Basically the same approach as above, despite the fact that not a resource is returned but some meta-information about what fields to post and what datatypes each attributes needs to have. Like in this example. Still, the creation endpoint is not located at /resource but on /resource/create
3. Creating by updating
A POST to /resource immediatly creates an empty resource and returns a link to this resource. The client then can follow this link to update the resource with the necessary data doing PUTs.
So what is the best approach that still follows the HATEOAs paradigm and why are all of these tutorials (and even books like REST in Practice) omitting this problem?
UPDATE:
I recently found out the Sun Cloud API seems to be pretty close to an "ideal" REST HATEOAS API. It not only defines some resources and does hyperlinking between them, it also defines media types and versioning. With all this theoretical discussion, it's pretty good to have a concrete exmaple. Maybe this helps some readers of this question.
Most tutorials and books about REST are very misleading, because there are many misconceptions about REST and no authoritative source other than Fielding's dissertation itself, which is incomplete.
REST is not CRUD. A POST is not a synonym to CREATE. POST is the method to be used for any action that isn't already standardized by HTTP. If it's not standardized by HTTP, its semantics are determined by the target resource itself, and the exact behavior has to be documented by the resource media-type.
With HATEOAS, a client should not rely on out-of-band information for driving the interaction. The documentation should focus on the media-types, not on the URIs and methods. People rarely get this right because they don't use media-types properly, and instead document URI endpoints.
For instance, in your example, everything has the application/xml media-type. That's the problem. Without proper media-types, there's no way to document resource-specific semantics when everything has the same media-type without relying on URI semantics, which would break HATEOAS. Instead, a drink should have a media-type like application/vnd.mycompany.drink.v1+xml, and your API documentation for that media-type can describe what to expect when using POST with a rel link.

Need help understanding REST API endpoints

I don't quite grok how to sensibly structure a REST (or REST-like) API.
Imagine an API for creating and sending out newsletter emails. You might have the following nouns/resources: newsletters (subject, body, etc.), mailing lists (collections of recipients), and recipients (email addresses and associated data).
So you could use PUT to create a resource and be returned its ID:
/newsletter
/list
/user
You could obtain information on a resource using GET:
/newsletter/[id]
/list/[id]
/user/[id]
You can update an existing resource using PATCH (or should this be POST?):
/newsletter/[id]
/list/[id]
/user/[id]
You can delete a resource using DELETE:
/newsletter/[id]
/list/[id]
/user/[id]
Is the above correct?
What endpoints are sensible for actions like sending a newsletter to a list, adding a user to a list?
Does the following make sense, and is it RESTfull?
/newsletter/[newsletter_id]/send/[mailinglist_id]
/list/[list_id]/add/[user_id]
/list/[list_id]/remove/[user_id]
Is it redundant or unhelpful to have list/[id]/add/[id] and list/[id]/remove/[id] endpoints for lists, when users could be added or removed via PATCH at /list/[id] ?
What about searching for a users' ID via a property like email address or name? Or getting a list via an identifier like its name or when it was created?
You pretty much nailed it, except with the /list/[list_id]/add/[user_id] and /list/[list_id]/remove[user_id], because you have verbs in the URL - that is the purpose of the HTTP methods. Change them to, for example:
PUT (or POST) to /list/[list_id]/users/ for adding a user to the list
and
DELETE to /list/[list_id]/users/[user_id]
For search, I'd go with parameterized url for the list of resources, like:
/newsletter/?name=dfjkhskdfh
These verbs are often confused:
To create an entity you use POST
To update - PUT
These things could be treated in the following way:
POST /newsletters/[newsletter_id]/mailinglists/[mailinglist_id]/mailingfacts - performs sending the letters, it's like adding a fact of mailing to the collection
/lists/[list_id]/[user_id] - adds a user to the list
/lists/[list_id]/[user_id] - deletes the user from the list.
Is it redundant or unhelpful to have list/[id]/add/[id] and list/[id]/remove/[id] endpoints for lists, when users could be added or removed via PATCH at /list/[id] ?
It is bad/unhelpful. One of the ideas of REST is that the end points are resources and not a Remote Procedure Call (RPC). add or remove is suggesting a procedure to call.
Further GET requests should be side-effect free, that is, they don't do any updates. Further Roy Fielding explains GET as:
retrieval of information that should be a representation of some resource
So GET is only for retrieval, not for sending data (i.e. which user to add/remove).
The other very dangerous problem with list/[id]/remove/[id] is that if a spider or your test framework is going around your site it could start deleting items.

In what situation should the client choose the unique resource ID for REST URIs and in which should the server specify it?

It looks like there are two ways I can make my REST API. I can have users created with a POST without specifying the URI and it will create the user and return the URI OR I can have the create the users with a PUT and specify the URI themselves.
When should one be used over the other? The key difference here is that in one method MY system is deciding what the unique ID and thus URI for the resource should be, in the other situation THEY are specifying what it should be when I create.
It basically comes down to whether you are willing to cede the control of resource naming to the client.
The biggest issue simply being dealing with conflicts (If I PUT /photo.png and you PUT /photo.png, is that OK?).
Answer those questions, and you're on your way.
When your user is specifying the resource ID, they can PUT to the URI; the ID that they are performing the PUT to is the specification of the resource ID.
When you are specifying the resource ID, they can POST to the URI of the parent / group; your system will assign a URI to the resource, and return that to the client so they can reference their created resource.
The answer to this question hinges on two more specific questions:
Do clients know the location of the resource to be created? (This might be the case if, for instance, users are accessed via the name of the user rather than a server-assigned ID.)
Do clients have a full representation of the resource to be created? (This might not be the case if some portion of your resource is computed by the server.)
If the answer to both of those questions is 'yes', then a PUT is probably appropriate. If you answered 'no' to either, then you ought to stick with a POST.
I can have users created with a POST
without specifying the URI and it will
create the user and return the URI OR
I can have the create the users with a
PUT and specify the URI themselves.
When should one be used over the
other?
Use the first.
In RESTful HTTP the client should never construct URIs. The service should be well-connected, which means that the client should only ever follow URIs given by the server and make requests to those URIs.
It creates better separation between the client and server, and makes it easier to make changes to the service without breaking existing clients.
(And yes, lots of existing APIs get this wrong)
There's a really good post by Fielding related to this topic here:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven