What should I do when there is no data to return from a REST endpoint? - rest

I have the following endpoint, and its happy path is this:
GET /messages/next
Response:
{
"date_published": "...",
"message": "..."
}
Normally, the response is as produced above, however sometimes there just aren't any "next" messages. My question is, in the case where there are no "next" messages do I respond with an HTTP 204 (No Response) or should I simply return {}?
What's the best practice in this situation?

According to W3 :
10.2.5 204 No Content
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation.
I think in your situation, it would be appropriate to return a 204 Http response, unless for some reason, a JSON payload would make for a better design decision for your program (i.e. you would like to return something more than just metainformation since 204 does not allow for a message-body to be returned).
Also, take a look at this post: REST API error return good practices

204 is quite tricky. The RFC says
The server has fulfilled the request but does not need to return an entity-body"
So there must be a request to fulfill and there is no need to return anything. This is not the case here. For a GET request the server needs to return a representation of the resource if its there. So either the resource is no there or it returns it. It cannot say "The resource is boring. I won't return it. Guess how it looks like".
Lets have a look at the response codes which come into consideration:
200 OK: the resource logically exists and a representation is returned in the body
204 No Content: the request is fulfilled and there is nothing to return
404 Not Found: the requested resource does not exist
These are all similar but there are subtle differences as there are different kinds of "nothing" to return.
Maybe you have a resource like /messages and a GET returns obviously the list of messages. This list can be empty: [] (or for security reasons rather {"messages": []}). Returning an empty list is fine and results in a 200. A huge benefit of empty lists compared to empty results (corresponding to null) is that the client can often handle an empty list using the same piece of code as it handles a non-empty list. No additional logic is required which reduces complexity and the possibility for errors.
Maybe there is logically nothing to return. This typically occurs when you have a PUT, POST, DELETE, or PATCH action. In these cases you may return a body (the old/new entity) but you needn't. When you do not, return 204.
Maybe the resource is not empty but does not exist. In this case you should return 404.
As an analogy think of resources as files (resources don't need to be files but they can and that's quite common for static HTML which happens to be the origin of HTTP): 200 means the resource/file is there but may be empty. 204 means the service is not obliged to return a file. 404 means the server was requested to return a file but there is no file to return.
So in your example GET /messages/next should return 404 when there is no next message and return 200 if there is a next message but this message is empty. It should never return 204.
When using HATEOAS the resource /messages/next should only be linked iff there is a next message.
Alternatively you could have a resource /messages/newest and request it using a conditional GET request (e.g. using the If-Modified-Since header).
Also have a look at this nice overview.

Related

Which http status code for 'entity not found'?

/persons?age=18
Imagine a search does not return any results (means: no entity found for the request).
If I'd return a 404 here, that would suggest that maybe the /persons path is invalid entirely.
Is there any accepted status code that could be return if the request was valid in general (means: the path exists, and the request parameters have been valid), but still there is no data to return?
204 is not suitable either, as this is used to tell the user "your request was 200 OK, but there will never be a response body to your request" (like for modifications).
Is there any accepted status code that could be return if the request was valid in general (means: the path exists, and the request parameters have been valid), but still there is no data to return?
200 is appropriate when the resource has a representation, even if that representation is an empty list.
# Request:
GET /persons?age=18
# Response:
200 OK
[]
Think "web search page that returns no results", downloading an empty file.
Jim Webber's 2011 talk may help with perspective here: the status codes and headers belong to the "transferring documents over a network" domain, not to your domain application protocol. The components that are specific to your application should be paying attention to the messages in the body of the response; the meta data is directed at general purpose components that are transferring documents.
Actually you should return 200.
The number of entities found does not change the http code.

In REST API call what should we return in case of empty result

I am having 2 services-
1. Client Service
2. Feature Service
Client Service asks feature service for feature corresponding to a client. If in the database no feature found for a client should what should we return?
1. 404 no resource found
2. 204 Success - No content
3. 200 Success - {features:[]} // Empty list
In practice, I have always returned a 200 with an empty list. The fact that the list is empty tells the consumer that, although nothing went wrong with the request, there are no resources associated with it.
The 204 is a fair compromise between the 200 and the 404 but I think that it adds minimal value.
I would personally shy away from throwing a 404 on an endpoint that returns a list since it is expected that there will be situations where the list is empty (that is potentially too broad of a statement). If the request was failing because of the resource associated with the list then I would definitely consider the 404 valid (let's say you had a user with a list of hats and the request for the hats was for a NOT FOUND user).
HTTP response should be 200, Just show "empty" result in TAG
You can return in two ways. 404 is not valid if no content is present.
a) 204 No Content
Explaination: The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation.
b) Return 200 and with empty body {};
You can find more at w3 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Is it correct to return 404 when a REST resource is not found?

Let's say I have a simple (Jersey) REST resource as follows:
#Path("/foos")
public class MyRestlet extends BaseRestlet
{
#GET
#Path("/{fooId}")
#Produces(MediaType.APPLICATION_XML)
public Response getFoo(#PathParam("fooId") final String fooId)
throws IOException, ParseException
{
final Foo foo = fooService.getFoo(fooId);
if (foo != null)
{
return response.status(Response.Status.OK).entity(foo).build();
}
else
{
return Response.status(Response.Status.NOT_FOUND).build();
}
}
}
Based on the code above, is it correct to return a NOT_FOUND status (404), or should I be returning 204, or some other more appropriate code?
A 404 response in this case is pretty typical and easy for API users to consume.
One problem is that it is difficult for a client to tell if they got a 404 due to the particular entity not being found, or due to a structural problem in the URI. In your example, /foos/5 might return 404 because the foo with id=5 does not exist. However, /food/1 would return 404 even if foo with id=1 exists (because foos is misspelled). In other words, 404 means either a badly constructed URI or a reference to a non-existent resource.
Another problem arises when you have a URI that references multiple resources. With a simple 404 response, the client has no idea which of the referenced resources was not found.
Both of these problems can be partially mitigated by returning additional information in the response body to let the caller know exactly what was not found.
Yes, it is pretty common to return 404 for a resource not being found. Just like a web page, when it's not found, you get a 404. It's not just REST, but an HTTP standard.
Every resource should have a URL location. URLs don't need to be static, they can be templated. So it's possible for the actual requested URL to not have a resource. It is the server's duty to break down the URL from the template to look for the resource. If they resource doesn't exist, then it's "Not Found"
Here's from the HTTP 1.1 spec
404 Not Found
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
Here's for 204
204 No Content
The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.
If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.
Normally 204 would be used when a representation has been updated or created and there's no need to send an response body back. In the case of a POST, you could send back just the Location of the newly created resource. Something like
#POST
#Path("/something")
#Consumes(...)
public Response createBuzz(Domain domain, #Context UriInfo uriInfo) {
int domainId = // create domain and get created id
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(domainId)); // concatenate the id.
return Response.created(builder.build()).build();
}
The created(URI) will send back the response with the newly created URI in the Location header.
Adding to the first part. You just need to keep in mind that every request from a client is a request to access a resource, whether it's just to GET it, or update with PUT. And a resource can be anything on the server. If the resource doesn't exist, then a general response would be to tell the client we can't find that resource.
To expand on your example. Let's say FooService accsses the DB. Each row in the database can be considered a resource. And each of those rows (resources) has a unique URL, like foo/db/1 might locate a row with a primary key 1. If the id can't be found, then that resource is "Not Found"
Though this question already have an accepted answer, I believe it's really an opinionated thing. Adding my two cents to help you make a more informed decision about the response code.
404 - Not Found. (Reference)
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
The resource may exist and you may not have permission to see the resource, will also be equivalent of Not Found. So 404 for a call where data doesn't exist is a very apt thing to do.
Now as for a non-existing URL; though 404 is a widely adapted response code 400 is a more appropriate code.
400 - Bad Request (Reference)
The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
If you put an invalid parameter in the request, what would be the response code?
If query param has a typo, what should be response code?
Answer to both is 400.
Most of the file-servers, return 404 for invalid URL because for an invalid URL they try to look for a file, which they can't find on the storage ~= Resource Not Found
Apart from the HTTP Status Code, the response will have some info about the error details, where one can be more descriptive about the error and can clear the ambiguity.
If client is calling with an invalid URL, it's an integration issue and should be caught at least during the sanity. No-way they will push the code to production without testing and catching this. Even if they do, God bless them!
tl;dr - 404 for not-found resource; 400 for not-found URL.
A 4XX error code means error from the client side.
As you request a static resource as an image or a html page, returning a 404 response makes sense as :
The HTTP 404 Not Found client error response code indicates that the
server can't find the requested resource. Links which lead to a 404
page are often called broken or dead links, and can be subject to link
rot.
As you provide to clients some REST methods, you rely on the HTTP methods but you should not consider REST services as simple resources.
For clients, an error response in the REST method is often handled close to errors of other processings.
For example, to catch errors during REST invocations or somewhere else, clients could use catchError() of RxJS.
We could write a code (in TypeScript/Angular 2 for the sample code) in this way to delegate the error processing to a function :
return this.http
.get<Foo>("/api/foos")
.pipe(
catchError(this.handleError)
)
.map(foo => {...})
The problem is that any HTTP error (5XX or 4XXX) will terminate in the catchError() callback.
It may really make the REST API responses misleading for clients.
If we do a parallel with programming language, we could consider 5XX/4XX as exception flow.
Generally, we don't throw an exception only because a data is not found, we throw it as a data is not found and that that data would have been found.
For the REST API, we should follow the same logic.
If the entity may not be found, returning OK in the two cases is perfectly fine :
#GET
#Path("/{fooId}")
#Produces(MediaType.APPLICATION_XML)
public Response getFoo(#PathParam("fooId") final String fooId)
throws IOException, ParseException {
final Foo foo = fooService.getFoo(fooId);
if (foo != null){
return Response.status(Response.Status.OK).entity(foo).build();
}
return Response.status(Response.Status.OK).build();
}
The client could so handle the result according to the result is present or missing.
I don't think that returning 204 brings any useful value.
The HTTP 204 documentation states that :
The client doesn't need to go away from its current page.
But requesting a REST resource and more particularly by a GET method doesn't mean that the client is about terminating a workflow (that makes more sense with POST/PUT methods).
The document adds also :
The common use case is to return 204 as a result of a PUT request,
updating a resource, without changing the current content of the page
displayed to the user.
We are really not in this case.
Some specific HTTP codes for classical browsing matche finely with return codes of REST API (201, 202, 401, and so for...) but this is not always the case.
So for these cases, rather than twisting original codes, I would favor to keep them simple by using more general codes : 200, 400.

API Development: When to return a BAD REQUEST HTTP Status Code (REST)

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?

What REST PUT/POST/DELETE calls should return by a convention?

According to the "REST ideology" what should be in the response body for a PUT/POST/DELETE requests?
What about return codes? Is HTTP_OK enough?
What is the reason for such conventions, if any?
I've found a good post describing POST/PUT differences: POST vs PUT
But it still doesn't answer my question.
Forgive the flippancy, but if you are doing REST over HTTP then RFC7231 describes exactly what behaviour is expected from GET, PUT, POST and DELETE.
Update (Jul 3 '14):
The HTTP spec intentionally does not define what is returned from POST or DELETE. The spec only defines what needs to be defined. The rest is left up to the implementer to choose.
Overall, the conventions are “think like you're just delivering web pages”.
For a PUT, I'd return the same view that you'd get if you did a GET immediately after; that would result in a 200 (well, assuming the rendering succeeds of course). For a POST, I'd do a redirect to the resource created (assuming you're doing a creation operation; if not, just return the results); the code for a successful create is a 201, which is really the only HTTP code for a redirect that isn't in the 300 range.
I've never been happy about what a DELETE should return (my code currently produces an HTTP 204 and an empty body in this case).
Creating a resource is generally mapped to POST, and that should return the location of the new resource; for example, in a Rails scaffold a CREATE will redirect to the SHOW for the newly created resource. The same approach might make sense for updating (PUT), but that's less of a convention; an update need only indicate success. A delete probably only needs to indicate success as well; if you wanted to redirect, returning the LIST of resources probably makes the most sense.
Success can be indicated by HTTP_OK, yes.
The only hard-and-fast rule in what I've said above is that a CREATE should return the location of the new resource. That seems like a no-brainer to me; it makes perfect sense that the client will need to be able to access the new item.
I like Alfonso Tienda responce from
HTTP status code for update and delete?
Here are some Tips:
DELETE
200 (if you want send some additional data in the Response) or 204 (recommended).
202 Operation deleted has not been committed yet.
If there's nothing to delete, use 204 or 404 (DELETE operation is idempotent, delete an already deleted item is operation successful, so you can return 204, but it's true that idempotent doesn't necessarily imply the same response)
Other errors:
400 Bad Request (Malformed syntax or a bad query is strange but possible).
401 Unauthorized Authentication failure
403 Forbidden: Authorization failure or invalid Application ID.
405 Not Allowed. Sure.
409 Resource Conflict can be possible in complex systems.
And 501, 502 in case of errors.
PUT
If you're updating an element of a collection
200/204 with the same reasons as DELETE above.
202 if the operation has not been commited yet.
The referenced element doesn't exists:
PUT can be 201 (if you created the element because that is your behaviour)
404 If you don't want to create elements via PUT.
400 Bad Request (Malformed syntax or a bad query more common than in case of DELETE).
401 Unauthorized
403 Forbidden: Authentication failure or invalid Application ID.
405 Not Allowed. Sure.
409 Resource Conflict can be possible in complex systems, as in DELETE.
422 Unprocessable entity It helps to distinguish between a "Bad request" (e.g. malformed XML/JSON) and invalid field values
And 501, 502 in case of errors.
By the RFC7231 it does not matter and may be empty
How we implement json api standard based solution in the project:
post/put: outputs object attributes as in get (field filter/relations applies the same)
delete: data only contains null (for its a representation of missing object)
status for standard delete: 200