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.
Related
I am exposing REST API's via an API Gateway so the requests go
Client => API Gateway => Back-end.
My back-end REST API's need to know about 2 users
1: Target User (on some requests)
the API needs this data for its action eg: groups/{abc}/add-user needs to know which user to add to a group
2: Calling User (on every request):
the API needs to check that this user is allowed to perform the action eg: only a group admin may add another user to the group.
I don't want other developers to get confused when looking \ adding to my API's so I want to create a convention. Is it a good idea to add the calling user ID as a header on every request?
eg: "user-context": "12345"
Before everyone screams "INSECURE!!!!", I should add some info to put your minds at ease
The calling user is allowed to know their user-id. It's not a problem
The target user is not identified by their real user-ID but by an obfuscated ID
The calling-user-id is actually passed in a signed JWT to my API Gateway. The API-Gateway validates the JWT, takes the calling-user-id and adds it to the back-end request. What i'm really asking here is whether the API-Gateway should put the calling-user-id in the header (eg: "user context": "12345") or the query string /myapi/?calling-user-id=12345
I've tried both approaches and they both work. I'm wanting to know which approach makes the most sense to other developers.
While making an Login/SignUp RESTful API, should the response contain any other user information e.g. User Profile, Permissions etc?
When I've done this previously the Login returns a token for the new session and possibly the userid. Then I've had other services that I call with this token to get a list of permissions etc. You should make each resource do a single thing, which allows greater flexibility and reuse. Like everything though... this is my opinion on it but there is no right or wrong way to do it.
The REST principle is that when you POST a request to the server, it should respond with a status to indicate success or failure (i.e. 201 created) and a pointer to the new resource just created.
In my comments above the resource being created is the session and the token is the identifier of that resource.
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.
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
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?