I'm designing a REST service and there's a need for a check to see if an address is correctly entered. What I'm thinking about is how you would design a REST interface for checking if an full street address is valid.
I have this /address service and I could for example do a POST /address/validation which returns a xml/json true or false, but it seems quite un-REST-ful to me.
Another way would be to do a GET /address?street=xxx&nr=xxx&zipcode=xxx (and a few more parameters) and return a 200 OK if correct or a 404 Not found if not correct, which may be more REST-ful?
I started doing option 1) but the more I'm thinking about it, option 2) with the GET feels better...
Ideas?
From a RESTful perspective, you're really returning a new resource, call it AddressValidation, that will contain your true or false value. So one approach would be to do a POST to /addressvalidation?street=xxx etc. I'd be fine with returning the result as JSON or using status codes. I'm not sure 404 is appropriate though; you might want to look at this discussion of validation return status codes.
I have the same issue with the GET /address?street=xxx&nr=xxx&zipcode=xxx approach as you propose it. To me, if it returns 404, that means that the address is literally not found (i.e. doesn't exist in the database), rather than that it's invalid (e.g. the zipcode is an invalid format; there can't be any such address). Again, see the linked discussion; it seems like 400 is a more appropriate response.
How about?
GET /addressValidity?street=xxx&nr=xxx&zipcode=xxx
=>
200 OK
Content-Type: text/plain
true
I feel doing POST and returning status codes (200 OK if correct or a 404 Not found if not correct) is more restful. Because you are not GETting something GET doesn't look appropriate. You are POSTing some information to server and it does some processing (validation) and returns some response.
Related
I am calling a REST API for a list of resources and getting the json response as below if atleast one resource is there.
{
"value": [
"res1_id",
"res2_id",
"res3_id"
]
}
and the HTTP response code is 200.
But when no resource is there the server is returning HTTP response code as 404.
My doubt it why it is designed that way(it is an enterprise product).
I was expecting a empty list as below and HTTP response code 200:
{
"value": []
}
I am not able to understand what design decision has been taken into consideration to return 404 instead of an empty json.
Please help me to understand the reasoning behind it.
What I am reading here is that you have a 'collection' resource. This collection resource contains a list of sub-resources.
There's two possible interpretations for this case.
The collection resource is 0-length.
The collection resource doesn't exist.
Most API's will treat a 0-length collection as a resource that still exists, with a 200 OK. An empty coffee cup is still a coffee cup. The coffee cup itself did not disappear after the last drop is gone.
There are cases where it might be desirable for a collection resource to 404. For example, if you want to indicate that a collection never existed or never has been created.
One way to think about this is the difference between an empty directory or a directory not existing. Both cases can 'tell' the developer something else.
You're trying to access a resource which does not exist. That's the reason for 404.
As a simple google search says
The HTTP 404, 404 Not Found, and 404 error message is a Hypertext
Transfer Protocol (HTTP) standard response code, in computer network
communications, to indicate that the client was able to communicate
with a given server, but the server could not find what was requested.
For your case
{
"value": []
}
This can be a status code 200 which means the resource is accessed and data is returned which is an empty array or you can customize it to a 404. But for that you've mentioned best is to return 200.
A status code of 404 is the correct response for when there is no resource to return based on a request you made. You asked for data and there is no data. It returns an empty response. They're relying on you to base your interpretation of the results on the status code.
https://en.wikipedia.org/wiki/HTTP_404
Some companies prefer making their errors known instead of hiding them. I know where I work we shy away from try catch blocks because we want our applications to blow up during testing so we can fix the problem. Not hide it. So it's possible that the dev that created the API wants you to use the status code of the response as a way of telling if the service was successful.
I am wondering what status code would I response with in my else statement from the code below:
if (album) {
res.status(200).json({error: false, data: {channel_id: album.attributes.channel_id, id: album.id}});
} else {
res.status(200).json({error: false, data: {message: 'There is not album found with this name'}});
}
I don't want to leave both of them 200 as I want from front end to manage messaged thru status code, for ex if it returns 200 I would say "Created Successfully" while in else case I would display "No data found".
What is your suggestion?
"No data found" should be 404.
"Created Successfully" should be 201.
For the 201 you should also specify a Location header for where another request can access the new resource.
Refs:
201 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2
404 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5
UPDATE:
I thought I'd expand on this, because the comments below point to thought processes I've battled with myself.
GET /some/thing responding 404 Not Found may mean a database entity not found, but could also mean there is no such API end point. HTTP itself doesn't do much to help differentiate these cases. The URL represents a resource. It's not a thing in itself to be considered differently from the thing it represents.
Some APIs respond 400 when a request is made to a non-existant endpoint, but personally I don't like this as it seems to contradict the way web servers respond to normal resource requests. It could also confuse developers building client applications, as it suggests something is wrong in the HTTP transport rather than in their own code.
Suppose you decide to use 404 for missing database entities and 400 for what you consider bad requests. This may work for you, but as your application grows you'll uncover more and more scenarios that simple status codes just can't communicate on their own. And this is my point..
My suggestion is that all API responses carry meaningful data in the body. (JSON or XML, or whatever you're using). A request for an invalid url may look like:
HTTP/1.1 404 Not Found
{ "error": "no_endpoint", "errorText":"No such API end point" }
Although, I agree with above post, I would also consider HTTP status 200 for some cases.
For example, you have Post and Post_Comments entities. When you request comments for give Post Id, you can have either have 404 (an error which you then need to handle on your REST API consumer side) or 200 which means that everything is OK and an empty array is returned. In the HTTP status 200 case, you do not need to handle an error. As an example, see how FB treats HTTP codes https://apigee.com/about/blog/technology/restful-api-design-what-about-errors
To follow and unfollow a person via a RESTful API, I have
POST /person/bob/follow
DELETE /person/bob/follow
What should these return in the body?
A collection of everyone you follow
The person you just followed / unfollowed
A status like { status: "ok" }
Nothing.
If you respond on errors using a HTTP server status, the status code does not say anything. If you respond with a 404 Not Found if there is no user Bob, or a 500 Internal Server Error if the database is broken, the only successful response you will ever get is OK. Users do not have to check the status code, they only have to check the HTTP status code.
I suggest you return nothing, and the fact that it is a successful response (i.e. 200 OK or 204 No Content) indicates that the operation was successful.
It all depends on your app/API design and the contract you are gonna define with the client/callers. But generally, in all the cases you should return status code to make your client aware of the result.
Like: respond(ResponseCode::OK, ...)
For POST: I'd return 'bob' object containing all of his followers + status code
For DELETE: I'd only return the status code.
Generally, for an API, I'm apologist to use the HTTP status codes instead of always OK with a code defined status.
This means that you can follow the existing standards for answers, and anyone who gets an error code will know roughly what happened/what they have to do.
Take a look at the wiki article http status codes for a usable reference manual.
Also, together with the error code, and because is an API we are talking about, it is useful to have a more descriptive message about the error. Something meaningful like error: "Auth token missing", or whatever standard you might come up with.
When it comes to creating resources, I generally answer back with 201 (Created) and the resource just created. Keep in mind that you might want to exclude some attributes from the resource (e.g. You're creating a user, you shouldn't return sensitive info such as the encrypted password)
Regarding the deletion of resources, generally return with either 200 (Ok) or 202 (Accepted) and no extra info.
Nevertheless, As #yek mentioned, it highly depends on the commitment with the API consumer. The most important thing is that you document the API decently and explain what should be the expectations.
We're authoring REST services, and there's a debate on what to do when someone requests a resource with a parent ID that does not exist.
Example: You are asking for a list of people associated with a company, so you GET with ID 1, but that company ID does not exist.
I would argue that the definition of REST says that we would simple return a empty list (resulting in a HTTP 204 (No Content)), since a HTTP Bad Request is for only malformed syntax, per the specification:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
I think it's also clearer that there was no error to be interpreted, the resource you are requesting does not exist.
Thoughts on best practice?
There is a SO discussion here: HTTP 400 (bad request) for logical error, not malformed request syntax although it's a bit more abstract, I'm torn if I should post this, or simply use that question.
If you do
GET /company/1
and there does not exist a company with id 1 then I think the appropriate HTTP status code is 404 - not found.
However, if you were to do,
GET /companies?id=1
Then I would return a 200 and an empty list of companies.
204 is not an error code, it is a success code, but that's a quibble. I don't often see it for empty lists, but rather success responses that simply have no meaningful content to respond with, such as a successful DELETE. For example, if you are returning JSON, a 200 with content of [] is what I would expect of an empty list of results. However, I don't think it is incorrect to use it in your case.
404 Not Found is a more common error for the case you describe. You are correct that it is not a syntax error, so 400 is not appropriate, but in fact, the resource is not there. 404 Not Found is an accurate response.
But in choosing between 200, 204 and 404, the correct answer is: it depends. The question is whether it is an error or not. 404 is more expressive (the client can tell that there is no such company) but you can trade expressiveness for security, meaning that it might be a good thing that a client can't tell whether the company with that id exists or not.
What about caching? only 200 will get cached, both 204 and 404 won't get cached. If this is important 200 with empty list seems ok. Not sure what about empty single elements?
When a client invokes my REST-ful service, it needs to know if the response came back was 'from me' or rather a diagnosis from the containing web server that something awful happened.
One theory is that, if my code is called, it should always return an HTTP OK(=200), and any errors I've got to return should be just represented in the data I return. After all, it's my code that gets the response, not the naked browser.
Somewhat self-evidently, if I'm using REST to generate HTML read directly by a browser, I absolutely must return an error code if there's an error. In the case I care about, it's always Javascript or Java that is interpreting the entrails of the response.
Another possibility is that there is some family of HTTP status codes that I could return with a high confidence that it/they would never be generated by a problem in the surrounding container. Is this the case?
I use the following:
GET
200 OK
400 Bad Request (when input criteria not correct)
POST
202 Accepted (returned by authorization method)
401 Unauthorized (also returned by authorization)
201 Created (when creating a new resource; I also set the location header)
400 Bad Request (when data for creating new entity is invalid or transaction rollback)
PUT
Same as POST
201 Ok
400 Bad Request
DELETE
200 OK
404 Not Found (same as GET)
I would not know how to avoid that some container returns codes like 404.
4xx codes are meant to handle client errors along with possibly some entity that describes the problem in detail (and thus would mean a combination of both of your mentioned approaches). Since REST relies on HTTP and the according semantics of status as well as methods, always returning 200 in any possible case is a violation of this principle in my opinion.
If you for instance have a request such as http://foo.com/bar/123 which represents a bar ressource with id=123 and you return 200 with some content, the client has no chance to figure out if this was the intended response or some sort of error that occured. Therefore one should try to map error conditions to status codes as discussed in REST: Mapping application errors to HTTP Status codes for example.