Correct Rest API endpoint - api

Hi Im working on a REST API for a e-commerce app and had a couple questions about which are the correct URNs to map some specific actions, having in mind the definition of URI stated on RFC 3986: A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource.
The action of sharing a post which receives an email and shares the post url via mail. Specific posts are mapped to /api/posts/id which is correct. The thing is I don't know how to map the URL of this action. A post to an URI like /api/posts/id/share is totally incorrect by definition of URI considering that share is an action and not a resource.
The action of resetting your password and the action of asking for a password reset email. Users are mapped to /api/users. Something like /api/users/password-reset-email and /api/users/password-reset would be incorrect following the same guideline explained before.

The key takeaway from the dissertation that introduced REST is:
Any information that can be named can be a resource...
Have a look at Resources and Resource Identifiers for more information.
In other words, an action is a resource.
In your own words, a URI is a sequence of characters that identifies an "abstract or physical resource". Just because an action doesn't easily map to a tangible object doesn't make it less of a resource.
There are status codes which only exist to respond to 'actions' (e.g. 202 Accepted).
All in all, POST /api/posts/{id}/share seems completely reasonable.
POST is really there as a 'catch all' for actions. In RFC2616 it says the "function performed by the POST method is determined by the server" and the function performed "might not result in a resource that can be identified by a URI".
The main points:
An 'action' should almost always involve POST
The 'action' performed should relate to the URI and body of the POST request.
You should return an appropriate status code (e.g. 200, 201, 202, 204, 4xx).

Related

CreateOrUpdate endpoint on DDD

I have a rest API for an application that I am developing. One of the endpoints receives the name, email and phone fields to create a new user (without password). Obviously the endpoint would be /users [POST]
Would it be correct to take advantage of this endpoint to, if the user already exists, update it with the new data? Or is it better to create a different endpoint (PUT) to update the user? If so I would have to put the business logic outside of this API, and I don't like that idea.
This question is not related to DDD, as DDD does not provide guidance on API design.
But to answer your question, whether or not you should use PUT or POST will depend on whether or not the action should be idempotent.
POST is typically used to create a new resource
POST is not idempotent, if the same request is sent multiple times there will be different results (new resource gets created each time). The same request sent to POST /users will create a new resource each time.
PUT is used to either create or replace an existing resource (not necessarily update).
The PUT method is idempotent, so if the same request is sent multiple times it will be the same as if it is sent once. The same request sent to PUT /users/1 will have the same result.
If you want to update part of the resource (update rather than replace), you can use PATCH.

What is the REST path naming convention to a nested resource that belongs to the authenticated user?

When an authenticated user wishes to access a resource which he exclusively owns, it seems redundant to specify the user id in the URL path.
Thus, in the following examples, which is the more appropriate way to name my API endpoint?
Example 1
User wants to change profile pic
PUT /users/{id}/profile-pic
or
PUT /profile/profile-pic
Example 2
User wants to add a hobby to his profile
POST /users/{id}/hobbies
or
POST /profile/hobbies
It's a joy to see people paying attention to their API design in terms of URI and responses. An API that is not well designed is going to quickly die since people will avoid using them.
Even if it's not going to be public and no one will use it aside from yourself or your team, think of your colleagues and your future self and take some time to think about how your URIs will look like.
Back to your question my friend, according to the hands-on restful API design patterns and best practices book, that I invite you to read,the REST API is composed of four unique archetypes, as
follows:
Document: The document is the base for a resource representation with a field and link-based structure.
https://api-test.​lufthansa.com/​v1/profiles
https:/​/api-test.lufthansa.​com/​v1/​profiles/​customers
Collection: A collection is also a resource, and it is a directory of resources managed by the API providers or servers.
https:/​/api-​test.​lufthansa.​com/​v1/​profiles/​customers/accountbalance
https:/​/api-​test.lufthansa.​com/​v1/​profiles/​customers/memberstatus
Stores: A store is a resource repository managed by the client. The store allows the API client to put resources in, choose URIs for the resources that get added, get them out, and delete them when it decides.
http:/​/api.example.com/cart-management/users/{id}/carts
http:/​/api.​example.​com/​song-​management/​users/​{id}/playlists
Controller: Controller resources are similar to executable methods, with parameters and return values. REST API relies on controller resources to perform application-specific actions that do not come under any of the CRUD methods.
POST /alerts/245245/resend
So, in your case, you can follow the API design of GitHub API. Look how they are retrieving the projects of an organisation. Yours would look this way:
PUT /users/{id}/profile-pic
POST /users/{id}/hobbies
I'm sorry for making it long, I wanted to base my perspective on something concrete.
When an authenticated user wishes to access a resource which he exclusively owns, it seems redundant to specify the user id in the URL path.
It shouldn't; the semantics of a resource identifier and the semantics of an Authorization header are different.
The fact that only Bob can get a copy of /profile/Bob is a matter of access policy, not message semantics.
Review Fielding's definition of resource. "Bob's profile" and "Alice's profile" are distinct nameable information (assuming for the moment that Bob and Alice are themselves distinct) and therefore should have different identifiers.
That's the "RESTful" answer.
In practice, HTTP has special rules about authentication, and the handling of authenticated requests means that you'll probably "get away with" treating the Authorization header as part of the identifier of the resource (particularly in the case where an authorized user is only allowed to access their own resource hierarchy).

Add instruction 'how' to perform a REST API request by adding header or body param?

Imagine a simple REST API that allows to create a user account, by sending a JSON resource to POST /users as in the following. By default it sends out a confirmation email to the user.
{
"username": "john#appleseed.com",
"password": "secret"
}
However sometimes there are good reasons for not sending out a confirmation based on the use case, e.g. another API client, or admins signing up users on their behalf.
Since it doesn't have any implications on the created resource but is more of an instruction how to create the user, should it be separate from the request body? What's the best way to do this?
Specify a custom header Confirmation: no-confirmation
Add a query param ?confirmation=false
Add a send_confirmation field to the request body
Let's take the options in order:
Adding a header value to indicate some semantic difference should be generally avoided. The API should be "browseable", meaning it should be discoverable following links only.
Adding a query parameter is, from REST perspective completely equal to creating another URI. It does not really matter how you expose it, the point is that the client needs to follow some links from the previous "state" it was in. This is actually ok, as long as the links to these resources indicate the different semantics you described: like creating users by admin, users creating themselves, etc.
Also note, that the API should not necessarily expose whether a confirmation is sent. The API should expose the "purpose", the server then can decide whether the use-case warrants a confirmation email.
Putting a send_confirmation in the JSON representation itself. This is ok, if this is a functionality available for the user. For example I can ask for a confirmation email. If I can't, and it is only used for differentiating different use-cases, then I would rather prefer option 2.
Summary: For the case you are describing I would pick option 2: different resources for admins and normal users.

HTTP POST for an idempotent action

I'm designing a Web API to serve mobile applications and I have an action that checks if a given authorization key still is valid or not. In this request I send sensitive data (like the vendor_id of a specific device). I've also learned it's important to use POST method instead of GET in order to protect the information. However, the same action is idempotent because it just checks the validity. My question is: should I use POST or GET for this purpose?
i prefer to use POST even though this is a GET per the REST architecture; i would create a separate url: /object/get when i am using POST to do a GET-like operation to distinguish it from POST-like operations which would be POSTs to /object

Is this a correct implementation of REST?

Im steadily building the resources of my API, however after much research on the correct ways to build a RESTful API, I have been unable to find an example of how 'complex' requests should be received.
For example, as part of the login process (which is little more than an authentication key update), the following URI is dispatched by the client:
/api/auth/login
There are no values on the URI, the resource is /auth/ and the command being triggered is /login/. The actual login details are sent to the server Authorization header.
Now, what prompted me to ask this question is as I was writing a command to allow the client to get a reminder of how long the key is valid for, I was immediately drawn to getkeyexpiration or something similar as a command name.
Suddenly I felt that this doesn't sound like what I read about in the 6 constraints, this feels more like operation calls.
So, based on the above examples, is this still a RESTful API? I am concerned as I cannot think of a way to perform this by simply using URI resource names and appended values.
Thank you
EDIT:
From reading this: http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
I am starting to understand that by naming resources and only resources with noun words, the context of how the server will operate becomes a lot clearer.
Regarding my above example:
/api/auth/login
I have used auth as a prefix of login, because that is the context of the resource. I am designing my system to be extendible and require a way to categorize resources on the URI level. Is there a standard way of doing this?
Your RESTful resources should be nouns, because HTTP provides the verbs.
I would suggest something like this instead:
/api/key
Which you can then POST to (with HTTP Authorization headers included) create a new key, returning something like this:
/api/key/1234ABCDBLAHBLAH
This is a key specific to your session, which you can then GET to retrieve details about it such as expiration time, etc. You will have to pass that key with each subsequent request, of course.
If the key stuff sounds clunky when discussed in the context of a RESTful API, it's because it usually is. Sessions are human/browser concepts, but RESTful APIs are application/integration concepts.
Since servers don't "log on" to other servers, this begs the question: if you're already OK with requiring the caller to pass an Auth header to your login API, why not just require it be passed for each API call, and forget the notion of keys altogether?