I am creating a simple API to validate a membership. Client will have to input a String ID and Server will check if the ID is a valid member of our, lets say, community. The ID must be numeric only, with length 10.
Quite simple right?
If the ID is a valid, of course we will return HTTP Status Code OK.
If the ID is contains alfabet, or less/more than 10, then we will return HTTP Status Code BAD REQUEST.
The question is, what is the best practive HTTP Status Code to return when the ID is numeric and length = 10, but is NOT a member of our community? and why is that.
The endpoints of a REST API are normally resources on which you act using HTTP methods like GET,PUT,POST,DELTE. When you do it like that, its much easier to decide which HTTP status to return.
So may be you could make an endpoint
/member/{id}
if a member with this id exists, return HTTP 200 and if you want some JSON with basic member info
if the id is valid, but no member exists, return HTTP 404 - NOT FOUND
if the id is not valid, length !=10 or contains invalid chars, return a HTTP 400 BAD REQUEST
Here you can find more about REST API design
Related
I'm using the HTTPClient ruby library for making some basic http requests to a REST service I have develop and im wondering now how can I get the response from the service when an error occurred (a status code like 400 or 500 is returned from the service).
What my service does is return the stock of a product in a center, so it takes two parameters (in the url): a product id and a center id. When I call this service passing correct product and center ids the service returns me a 200 - OK status and the stock of the product (for example, 8.0 indicating there are 8 units of the product in that center). However, if I pass a wrong product id (one that is not in our database) the service returns 400 - Bad Request and an error message indicating that the id does not exists.
So I have a method like the following in Ruby
def stock(product, location)
response = #client.get_content("stock/#{product}/#{location}")
end
#client is an instance created with HTTPClient.new that I have configured. On passing ''right'' arguments it returns me what I want so it is well configured
My problem now is that when the service returns an error status code an HTTPClient::BadResponseError exception is thrown and I'm not able to retrieve this error in the response variable.
Is there a way to get the response from the service, no matter which status code it returns? I tried using begin...rescue and I can get some information like the status code and the reason phrase, but not the content of the response (the error message)
You're using get_content which skips a few steps and returns the content. Instead step back and use get which will return a more complete response structure that includes, among other things, the status field you want:
def stock(product, location)
response = #client.get("stock/#{product}/#{location}")
body = response.body
status = response.status
end
Let's suppose to have an HTTP POST that accept as input a JSON with some data and it must validate these data. The method should return also a validation message in the response body.
Ex.
{
"A" : 1,
"B" : 1,
"C" : 3
}
Suppose to have some validation rules defined over the JSON, for example (A + B) should be less than C parameter.
I have some doubts about the HTTP status code.
If the JSON is valid the HTTP POST should returns 200
If the JSON is not valid (missing parameters or wrong types) the HTTP POST should returns 400
But in case the JSON is valid (there are all the requested parameters and the types are correct) but the parameters don't respect the defined rules (A + B < C) what should be the HTTP Status?
200 and than an explanation in the response body?
400 and the explanation in the response body?
Is there the need to differentiate the HTTP Status from the Validation rules Status?
Cheers
That's what status code 422 ("Unprocessable Entity") has been designed for.
See https://www.greenbytes.de/tech/webdav/rfc4918.html#STATUS_422.
It all depends on the use-case / functionality you want to achieve.
If you want to make it easy for others to work with valid messages, I would perhaps return 2xx only if the message is completely valid, and in all other cases return 4xx. In this case the caller does not need to parse the result, which makes it easy to work with.
If the use-case is to provide some analytic service that others will use to analyze messages, not specifically to use the message itself, then I would return 2xx with the result of the analysis unless the message can not be parsed (not a json for example), in which case 4xx is warranted.
your response need to be 400 with the follwing message: "Bad Request: parameters don't respect the rules".
400 error
I'm using Spring Boot and controllers I'm feeling difficulty to treat some errors, for this reason I have some questions about the most appropriate status for each of the following situation:
PUT Object no Id
Put the URL localhost:8080/users/1 with a JSON without the Id attribute.
PUT Object with different parameter Id
Put the URL localhost:8080/users/1 with a JSON with Id 2, ie, different from what was passed in the parameter.
GET with invalid parameter
GET on the URL localhost:8080/users/search?sex=ABC, or an invalid sex for the system (the correct would be sex = male or female?).
JSON POST with id
Performing a POST in order to persist the data (create) but with id.
Case 1. Id is in the uri : no error
Case 3. "400 Bad request" is acceptable. (client should not retry the exact same request)
Cases 2. and 4. Just ignore the Id from the body and return 200 or return a "400 Bad Request"
Note that the id shouldn't be seen as an attribute of the resource: it is a part of the resource identifier.
I want to specify the various exceptions/errors that have to be returned while making an API call. How do I achieve this with Apiary.
Kyle's response is indeed correct. I will just add that if you want to add little bit more semantics to this you can write the other possible responses like this:
## POST /users/resendVerification/{userId}
Resends the user's verification code to the email address on record.
+ Response 201
+ Response 403
Returned if the user does not have access to the requested account
+ Body
+ Response 404
Returned if a user was not found for the given userId
+ Body
Note: The + Body is needed (even though it is empty) to distinguish the description from a message-body.
I'm not aware of a specific syntax for error codes. In the past I've simply used bullet points. For example, this is my code for a re-request verification code API.
## POST /users/resendVerification/{userId}
Resends the user's verification code to the email address on record.</br>
• 403 is returned if the user does not have access to the requested account</br>
• 404 is returned if a user was not found for the given userId</br>
+ Response 201
Hope that helps.
In my Cappuccino frontend I'm using Ratatosk to make queries to a RESTful JSON-based API.
When I create a new resource with
[myNewResource ensureCreated];
my backend returns the status code 201 and a Location header with the URI of the newly created resource. The response body is empty. As far as I know, that's the way a REST API should react to successful POST requests.
But upon receiving the response, Ratatosk calls
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
(in WLRemoteLink.j) and tries to decode the response body. This throws an error because the response body is empty. As a consequence, the request is repeated infinitely.
How should I go about this? Am I supposed to return the whole resource in the response body?
EDIT:
Returning the ID in the response solved the problem, like
{"id":1}
Ratatosk expects the status code 204 (no content) if the response is to be empty. Otherwise it expects the full representation of the resource which was just created (which it uses to populate server side dynamic properties locally like created_at).