REST and validation of one field - rest

I'm no expert in this so please tell me if I'm way off :)
I'm trying to define a REST service that handles accounts.
/Accounts/32 (GET to fetch one)
/Accounts (GET to fetch all)
And so on...
However, in the sign up process, before an account is created, I would like to verify a couple of fields, like E-mail and ssn, async before the account is created.
How should I go about doing so? I just want to know if they exist in a combination but I shouldn't get a resource back since it's none of my business. :)
Is it valid to do something like this?
/Accounts?ssn=123&email=a#email.com&operation=verifyexistance
Thanks
// Johan

Interesting question, for me I would prefer to do the following:
HEAD /accounts?ssn=123&email=a#email.com
if response status code is 200 then the resource exist on the server
if response status code is 404 then the resource not available and you can continue with registration
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.

I like Anas Salman's answer, which suggests the use of HEAD. That's the ideal method.
But I also think that GET is perfectly fine. You are requesting to get information about the resource (the /accounts collection).
GET /accounts?ssn=123&email=a#example.org
When /accounts sees a request in this format (a GET request with an SSN and email address provided), it has enough information to know to respond appropriately with an affirmative or negative.
The addition of an "operation" verb in the query string is the only unRESTFUL part of your example.

Related

GET or POST for stateless RESTFUL API

I'm writing a stateless API. You send it a document, it processes the document, and then returns the processed document. I'm struggling to understand how the RESTFUL rules apply. I'm not retrieving data, creating data or updating data on the server. There is no data on the server. What do I need to use in this case as the http method and why?
Good news - you are right that it is confusing.
Nothing on the server changes in response to the request. That suggests that the request is safe. So GET is the natural choice here... BUT -- GET doesn't support message payloads
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
HEAD, the other ubiquitous safe method, has the same problem (and is unsuitable when you want to return a document in any case).
The straight forward thing to do at this point is just use POST. It's important to realize that POST doesn't promise that a request is unsafe, only that it doesn't promise that it is safe -- generic components won't know that the request is safe, and won't be able to take advantage of that.
Another possibility is to look through the method registry, to see if somebody has already specified a method that has the semantics that you want. Candidates include SEARCH and REPORT, from the WebDAV specifications. My read of those specifications is that they don't actually have the right semantics for your case.
A Lot of ways to do what you want. But here is a small guideline.
I would create an endpoint that receives the document:
/receive_document
with a 'POST' method. Since you are 'sending' your document to the server
I would create an endpoint that serves up the processed document:
/processed_document
with a 'GET' method. Since you want to retrieve / see your document from the server?
The problem that you are trying to solve is mainly related to the document size, and processing time before returning the response.
Theorically, in order to use a restful approach, you have an endpoint, like yourhost.com/api/document-manager (it can be a php script, or whatever you are using as backend).
OK, so instead of naming the endpoint differently for each operation type, you just change the HTTP method, I'll try to make an example:
POST: used to upload the document, returns 200 OK when the upload is completed.
GET: returns the processed document, you can also return a different HTTP code, in case the document is not ready or even different if the document hasn't been uploaded. 204 no content or 412 precondition failed can be good candidates in case of unavailable document. I'm not sure about the 412, seems like it's returned when you pass a header in the request, that tells the server which resource to return. In your case, I think that the user processes one document at time. But to make a more solid api, maybe you can return an ID token to the user, into the POST response, then forward that token to the GET request, so the server will be able to know exactly which file the user is requesting.
PUT: this method should be used when updating a resource that has been already created with POST
DELETE: removes a resource, then return 204 or 404
OPTIONS: the response contains the allowed methods on this endpoint. You can use it to know for example which privileges has the currently logged user on a resource.
HEAD: is the same as a GET call, but it shouldn't return the response body. This is another good candidate for you to know when the document has been processed. You can upload with POST, then when the upload is done, start some kind of polling to the same endpoint with the HEAD method, finally when it will return "found", the polling will stop, and make the final GET call, which will start the download of the processed document.
HTTP methods are a neat way of managing HTTP communications, if used properly are the way to go, and easily understandable by other developers. And not to forget, you don't have to invent lots of different names for your endpoints, one is enough.
Hope that this helped you a little... But there are loads of guides on the net.
Bye!

REST HTTP Response status code to indicate client input is non-verified?

We have POST API that gives particular user's contact details in response. But as this is confidential data, to access this detail, anyone accessing it needs to put verified mobile number.
The request looks like:
POST /api/userdetails
{
"userid": 123,
"mobile": "+1394839843"
}
What should be status code if "mobile" number is not a verified number in our database?
What should be status code if "mobile" number is not a verified number in our database?
From a very high level: think about what you would expect a plain old web site to do if a user submitted a form with a "not verified number" and do that.
The charts in Michael Kropat's Stop Making It Hard breaks the process down into more specific questions.
Is there a problem with the request? That's clearly a yes, here, so we know immediately that you'll want to use some code from the 4xx class.
From there, it's just a matter of looking through the semantics of each code and seeing which one best fits.
400 Bad Request is the generic client error, so you use that if you can't find a better match.
403 Forbidden is roughly "I understand your request, but decline to act upon it." This is most commonly associated with authentication and ACLs, but the standard doesn't actually require that. Given your description, it's not a bad match.
422 Unprocessable Entity from WebDav, is another possibility. I'd reject it, on the grounds that the schema of the message body is perfectly correct, the problem is that the specified value isn't aligned with the current state of the server. You might want to review a previous discussion about 400 vs 422

Use of HTTP 204 vs 200 vs 404 to safely signal that a resource doesn't exist

In my REST API I have the normal CRUD endpoints for some resources.
If I do a GET /items/42 and there is no such item, the normal behaviour would be to return a 404 NOT FOUND.
However, one scenario concerns me. In this scenario, a client needs to check if a resource (which is implicitly idenfitied by a token) exists, and if not, create it. So, the client would try to retrieve the resource, and if a 404 is received the client application would display the UI necessary for creating the item, and then proceed to POSTing the new resource. In a way, this is a special kind of resource, because since its ID is derived from other parameters, it's known even before creation. As an example, consider a user sign-up procedure; the client would ask "Do I exist? If no -> register me".
My concern is really whether I ever need to worry about "spurious" 404:s? Considering a server is usually surrounded by API gateways, reverse proxies and such, is there any risk that a 404 NOT FOUND could be produced by a surrounding entity due to some temporary error not related to the REST server itself? If so, it could trick the client into believing that the item is not created yet, and that it should now be created. Even if the resulting POST request to create the item would fail because the item already exists, this isn't very nice because the user may have entered data etc for no reason.
Is this a problem to take into account or just overly paranoid? I guess if clients can't trust a 404 to be idempotent (until the resource is created, of course), many other issues arise. Is there any actual situation where an API gateway or similar would report a 404 on its own?
If this is a valid scenario, do I need a "safer", more explicit response saying that the request definetely succeeded but the resource wasn't found, such as responding with a 200 OK with an empty JSON body or a {isRegistered: false}, a 204 NO CONTENT, or similar? This opens up for other strange things - if a request for a resource that doesn't exist would respond with a 200 accompanied by an empty body, perhaps creation of the item would be a PUT rather than a POST, etc? This seems like a can of worms... It all boils down to "Does a 404 guarantee that the given resource doesn't exist?".
404 is pretty unambiguous : the resource wasn't found and it's a client error (4xx). Normally, server-side errors (5xx) can't interfere and create spurious 404's here.
As an alternative, if the resource to be created is linked to another resource in a unique way, you could use OPTIONS to ask the server if it already exists.
For instance :
OPTIONS /visitors/7883930/user-account
=> Allow: POST,OPTIONS (doesn't exist)
=> Allow: GET,OPTIONS (exists)
The key here is to have a URI that allows accessing the resource without knowing its ID. It is not always possible though.

REST delete in reality update

i'm currently trying to build simple REST api with one endpoint or users looking like this:
GET /users - get all
GET /users/{id} - get one
POST /users - create
PUT /users/{id} - update
DELETE /users/{id} - delete
The problem is with DELETE, because DELETE in reality only UPDATE user resource with status REMOVED. Is it ok? And which status should I return? I'm currently returning 202 Accepted, as i believe that saying "Resource is accepted to be removed" is ok, but maybe there should be just 200 OK
When designing an API, you should always consider what the giving action means for the user of the API.
The user would not really want to know what happens behind the scenes, but only want a clean and understandable set of actions.
So for you delete action, you should consider, "will this delete the item, from the users perspective?"
Responding with status code 200 most often fine, but remember to send some content with it to support it.
Using many different status code for success does not really give value, so be careful.
RestApiTutorial says this.
DELETE is pretty easy to understand. It is used to delete a
resource identified by a URI.
On successful deletion, return HTTP status 200 (OK) along with a
response body, perhaps the representation of the deleted item (often
demands too much bandwidth), or a wrapped response (see Return Values
below). Either that or return HTTP status 204 (NO CONTENT) with no
response body. In other words, a 204 status with no body, or the
JSEND-style response and HTTP status 200 are the recommended
responses.
But you can use It for your prupose, if It do your Api logic easier to understand to the user.
I Hope It helps you.
The question that you have to ask yourself is:
Does the resource after the DELETE will still be available to the client?
If the answer is yes then I would suggest to use a PATCH you can even use the RFC6902 for that.
If the answer is no then DELETE is fine.
But since you have mention that the idea is to flag the user with a status delete I guess you have the intention to query all deleted user at some point or do something useful with it. Witch seems to be a client [admin] use case so PATCH sounds appropriate.
Regarding the status for DELETE. Some people may prefer to use the 204 No content since you are expecting the resource to be removed.

Returning REST 400-Bad Request with additional information

Hey,
I have a REST based server, and in some cases I want to return a failure code (400 for example), BUT, I wish to add additional URL.
Something like - "failure, but here's what you can do now.."
Is there any good convention to do so?
Is it even a good idea to return error with additional information?
Thanks,
Udi
It is always a good idea to return additional information in an error message. The HTTP spec itself says so: "Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user."
One thing to watch out for: some versions of Internet Explorer will not show the user your additional error information if it is not a certain number of bytes. Make sure your response entities for error messages are at least 512 bytes to be sure.