HTTP POST for an idempotent action - api

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

Related

Putting the calling user-id into the header of a REST-API

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.

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.

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.

Architecturing testmode/livemode using OAuth 2 token

The title is a bit obscure. I'm interested about some feedbacks on a specific architecture pattern.
Let's take as an example the Stripe API: when you are using this API, the system is basically broken into two parts: live mode and test mode. If you hit the "/customers" end-point, you can either retrieve test mode customers or live mode customers, based on the type of API key used.
I'm asking myself how I could implement such a pattern using an OAuth 2 access token.
In my workflow, I have a single application page (JavaScript) that communicates through my API. I have a "live"/"test" switch, so basically my whole website is replicated into two distinct environments.
When I log in into my application, my authorization server creates a unique access token (OAuth 2 Bearer token), that is send for each requests. But obviously, my access token is tied to the "session", not an "environment" (live or false), so if I want to implement a switch live mode / test mode, I cannot rely on the token, because the token is "generic".
I've thought about two options:
Depending on live mode or test mode, I send an additional header to all my request (like X-Livemode which is either true or false). Then, in my back-end, I reuse this header to automatically adds a filter on all my requests.
If I switch to live mode or test mode, I ask my authorization server another access token. This would means that access token would have additional context information. However this seems a bit complicated, and I'm not sure that OAuth 2 spec allows token to have such additional information.
I'm not sure if this post is clear or not :p.
The second part of the question, is what is the best way to implement such a system where all the resources are basically duplicated between live / test mode ?
In my understand, it should be as simple as adding a "isLivemode" property to all resources, and make sure that all my SQL queries are aware of this. Is this correct?
Thanks!
A much simpler solution I've used in the past (albeit a bit of a workaround) is just to append "live" or "test" (base64 or hex encoded) to the api key, like so:
Imagine your actual key is:
9a0554259914a86fb9e7eb014e4e5d52
In your key presentation, present your key to the user as:
9a0554259914a86fb9e7eb014e4e5d526c697665
Then use a regular expression to strip off the known characters.
Alternatively, if you're equipped to handle key-value maps, a more "OAuth2-spec" approach would be to generate unique keys for live and test and do a key-value map lookup on the request to determine if one belongs to live or test.

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?