Best Practice - API successful response message - rest

My current project API using this response on success:
if it's create -> it will send created object (201)
if it's update -> it will send updated object (200)
if it's delete -> it will send 204 response
Most of recommendation for example http://jsonapi.org/ never said about successful message to shown to user. I've followed their rules to keep returning object or 204 on success
What if I want to show to user alert "Successfully created" or "Successfully updated"?. Should the message come directly from server or client side (type it down or use some locales)?

You should review the RFC 7231, and it's description of 200 OK
The payload sent in a 200 response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:
POST a representation of the status of, or results obtained from, the action;
PUT, DELETE a representation of the status of the action;
So yes, using the response body to present a representation of an alert to the user is fine.
For 201 Created, the same basic rule applies
The 201 response payload typically describes and links to the resource(s) created.
204 No Content is not similar, for the simple reason that "No Content" refers to the message body; 204 is one of the ways that you can indicate to the client (and intermediary components) that the 0 byte payload is not an error.
The 204 response allows a server to indicate that the action has been successfully applied to the target resource, while implying that the user agent does not need to traverse away from its current "document view" (if any). The server assumes that the user agent will provide some indication of the success to its user, in accord with its own interface, and apply any new or updated metadata in the response to its active representation.

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.

What status code should we return if the POST succeeds but does not result in creating anything new?

We have an endpoint which when you post create a new version of resource and returns a 201 and the location of the newly created resource. It determines the new version number based on a comparison of the current version and the version being posted (using a semver like ruleset).
If the version you post is identical to the existing version then no version number is updated. What should we return in this case?
We could just return a 201 even though we have not technically created anything.
I don't want to return a 409 as its not really a conflict, like when you post something with the same id. If you posted the same thing when the existing version was slightly different then you would happily get a 201.
We could just return a 200, but then that would seem weird, and increases the response codes that the users have to deal with
Does the idempotency of the 201 response matter?
Any better suggestions?
How about 303 - See Other? Seems to fit. I draw your attention to this sentence
from the spec at https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource.
That sounds like what you want to do to me. Here's the rest of it.
10.3.4 303 See Other
The response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.
The different URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).
Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303
I am a bit puzzled by the other answers as some get it almost right. So, let's clear up things a bit. If all requests are indeed performed with the POST method, in the context of ReSTfulness, they are supposed to modify state on the target server. Otherwise, the meaning of POST is a bit relaxed as you can see in RFC 7231, sec. 4.3.3.
Since the intent of the requests is to create a new version of a resource, they have failed if a version with the given presentation already exists. This would disqualify any 2xx-class response codes. From section 6.3:
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted.
If you absolutely wanted to, you could go for 202/Accepted, which "is intentionally noncommittal." This is a bit of a stretch, though, as this status code is intended for queued processing. I would advise against it.
The 204/No Content code suggested by others is a bit of a poor choice. It were absolutely correct if you POSTed to the resource you were updating, though.
As the result is neither informational (1xx) nor a fault by the server (5xx). Let us have a look at the 3xx class first. From section 6.4:
The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.
One of the most prominent one here would be 304/Not Modified. While sounding like a perfect fit, this code is unfortunately not applicable here. It can only be returned in response to conditional GET or HEAD requests.
302/Found may sound like the next best fit. However, this code is intended for temporary redirects, which is in all likelyhood not what you want.
As has been suggested here, 303/See Other is indeed a good choice:
The 303 (See Other) status code indicates that the server is redirecting the user agent to a different resource [...] which is intended to provide an indirect response to the original request.
[...]
This status code is applicable to any HTTP method. It is primarily used to allow the output of a POST action to redirect the user agent to a selected resource
All other 3xx codes are dealing with various forms of redirects that hardly relate to the situation here.
A final look, 4xx-class of status codes. From RFC 7231, sec. 6.5:
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation 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.
Very few of these are actually deeling with the request body. Two of those who do would stand out here: One is 400/Bad Request, which is by design overly broad. It is - if you will - a catch-all solution. However, this would imply that the request body is malformed (as in syntactically incorrect) in some way, which is probably not the case.
More interesting is 409/Conflict. From the RFC (emphasis mine):
The 409 (Conflict) status code indicates that the request could not be completed due to a conflict with the current state of the target resource.
The wording of the definition places this code close to the PUT method, but is not exclusive. To reiterate the definition of the 4xx codes:
These status codes are applicable to any request method.
422/Unprocessable Entity is a contender, but it implies a semantic error, which really isn't the case here.
Ultimately (drumroll) the final piece of the puzzle could be found in section 4.3.3:
If the result of processing a POST would be equivalent to a representation of an existing resource, an origin server MAY redirect the user agent to that resource by sending a 303 (See Other) response with the existing resource's identifier in the Location field.
Note the "MAY." So you can really choose between 303 and 409. I feel 409 were the better fit, as clearly an earlier request introduced a state that is incompatible with the current one. OTOH, 303 may be the politer way to go and is closer to the standard. Either way, as a consumer of your API, I would really like to know if my requests failed. And be it by not having any effect whatsoever.
If nothing has been created by the operation, 201 is not suitable for that:
6.3.2. 201 Created
The 201 (Created) status code indicates that the request has been fulfilled and has resulted in one or more new resources being created. [...]
See below some options you could consider if the operation succeeds:
6.3.1. 200 OK
The 200 (OK) status code indicates that the request has succeeded. The payload sent in a 200 response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:
[...]
POST: a representation of the status of, or results obtained from, the action;
[...]
Aside from responses to CONNECT, a 200 response always has a payload, though an origin server MAY generate a payload body of zero length. If no payload is desired, an origin server ought to send 204 (No Content) instead. [...]
6.3.5. 204 No Content
The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. [...]
If the operation fails:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot 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).
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415 (Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
A 201 Created should be used whenever you creating a new resource without doubt.
As defined in HTTP Method Definitions RFC, either200 Ok or 204 No Contentis an appropriate response if the operation does not create a new resource depending on the response body content.
The action performed by the POST method might not result in a resource
that can be identified by a URI. In this case, either 200 (OK) or 204
(No Content) is the appropriate response status, depending on whether
or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
Now, coming back to your original question about what to use when the operation is successful and there is nothing to return, you should use 204 No Content. This status code is specifically meant for scenarios where the requested operation is successfully completed but there is no additional relevant information that the server can provide.
The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
I don't think that for this case the idempotency is an issue, because the state of the system is not the same as it was in the inicial request, because the entity now exists, so you can respond with a different code.
200 should be fine, but it is a little weird as you said.
I have never use this, but I read that for some case you should redirect with a 302, to make a get for other resource, in this case I think this apply, return a 302 and make a get pointing for the old semver, assuming that you have a get endpoint for this entity.
If the POST'd resource has the same version number, but different data, then a 409 would be fitting. But if the data is the same as what's already stored, then a 409 might not be required. Through process of elimination I would say 200 OK would be fine.
We could just return a 200, but then that would seem weird, and increases the response codes that the users have to deal with
If this is a costly concern, consider eliminating the 201, not the 200. The fact of the matter is that for any decently complex service there may be at some point a situation where a 20X (where X is not 0) is applicable. So does that mean we code with each of the 20X responses in mind and spend time checking if our services has situations where 20X is preferred over 200? I suspect not. So unless there is a specific reason to respond with a 20X, for example to deal with a specific use case, then just use 200 and reduce the amount of coding and documenting required. I suspect for most scenarios, the calling client does not care.
Ultimately, the correct answer probably depends on whatever client is consuming your API. If you are building the client too, you could do whatever you prefer... (Just don't get too crazy.)
Assuming you are writing the API and client:
My opinion/suggestion is...
If there IS a new version number: The 201 HTTP status code would fit will.
If there is NOT a new version number: The 200 or 204 HTTP status code would fit well.
If there is no benefit to the client knowing the version number has changed or is the same: Send the 200 HTTP status code.
If you don't control the client consuming your API: Obviously defer to what they expect.
You may also wish review all of the HTTP Status Codes in the HTTP RFC spec. The above status codes also link directly to the relevant section.
201 : when new version is created
202 : when existing version is updated
204 : when request is accepted but no processing is done
by def, 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.
So its slight tangential to your needs but I think its the best fit.

POST that doesn't create a resource

Assume the system manages users. Users are exposed via the following URL - /users. A particular user is exposed via the following URL - /users/{id}. Users have reports exposed via the following URL - /users/{id}/reports.
One operation consists of generating a report. The appropriate HTTP request is a POST on /users/{id}/reports. However, under certain conditions, a generated report would be exactly the same as the last generated report. Therefore, I thought that returning the last generated report in this case is a good approach.
I also know that in such case, no resource will be created.
Is there a correct RESTful way to handle this case? Maybe returning a special code?
Is there a correct RESTful way to handle this case? Maybe returning a special code?
Stepping back for a moment: a perfectly straight forward way to handle the "create" use case looks like
client POSTs a request to /users/1/reports
the origin server creates a new resource and calculates a new identifier for this resource (/users/1/reports/a)
the server returns a response that indicates that a new resource has been created, the location of that resource, and its current representation.
The indication that a new resource has been created is the status-code: 201.
The location of the newly created resource is described by the Location response header.
The location of the content is described by the Content-Location response header
The current representation is the message body of the response (no surprise).
HTTP/1.1 201 Created
Location: /users/1/reports/a
Content-Location: /users/1/reports/a
...
<representation of the report goes here>
In your case, where the resource already exists, then things look pretty much the same. To avoid implying that we have created a new resource, the status-code is changed to 200, and the Location header is dropped.
HTTP/1.1 200 OK
Content-Location: /users/1/reports/a
...
<representation of the report goes here>
If you prefer that the client retrieve the report representation using the identifier of the previously generated report, then you should use 303 See Other
It is primarily used to allow the output of a POST action to redirect the user agent to a selected resource, since doing so provides the information corresponding to the POST response in a form that can be separately identified, bookmarked, and cached, independent of the original request.
HTTP/1.1 303 See Other
Location: /users/1/reports/a
...
This pattern is commonly referred to as Post/Redirect/Get
i'd use 304 Not Modified in cases where the report is not modified. This should tell everyone, that the ressource didn't change since the last export and normally no further content is transmitted. This could also be used to instead refer to your older results if you cache those. Generally the 304 is not used for posts, but the use of a post to jus trigger the creation of a log can be considered a bit exotic as well.
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields.
RFC containing explanation of the 304 Status Code
If the creation worked i'd send a 201 created and use the location header as pointer to the new file.

Response status code for searches in REST APIs

Suppose, we have the following API:
GET /api/guests/{id}
GET /api/guests?name=dummy
Which status code should I return when there are no guests matching criteria? I mean no guests with name dummy.
Should it be 404, 204 or 200 with an empty array?
The proper status code for each situation
Consider the following situations:
GET /api/guests?name=dummy
It's an operation that requests a representation of a collection. If no items match the search criteria, return a 200 status code with an empty array in the response body, indicating that the request was successfully received, understood, and accepted by the server, and collection itself exists but the search returned no results.
GET /api/guests/{id}
It's an operation that requests representation of a single resource using its unique identifier. If no resource was found return a 404 error, indicating that the server did not find the resource with that identifier.
More details
Have a look at the status code definitions in the RFC 7231 (which updates the old RFC 2616). It's pretty clear:
6.3.1. 200 OK
The 200 (OK) status code indicates that the request has succeeded. The payload sent in a 200 response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:
GET: a representation of the target resource;
HEAD: the same representation as GET, but without the representation data;
POST: a representation of the status of, or results obtained from, the action;
PUT, DELETE: a representation of the status of the action;
OPTIONS: a representation of the communications options;
TRACE: a representation of the request message as received by the end server.
[...]
6.3.5. 204 No Content
The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. Metadata in the response header fields refer to the target resource and its selected representation after the requested action was applied.
[...]
6.5.4. 404 Not Found
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent.
[...]
The HTTP status codes are organized in classes. Have a look at this:
6.3. Successful 2xx
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted.
6.5. Client Error 4xx
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
[...]
I would return 200 with an empty array...
Or a 204 (No Content)
A 404 is when a resource isn't found.
Your resource in this case is the collection of guests... which exists.
200 and empty list of items. As the guest ressource in general is found but it has no matching items for your query

HTTP GET Request Status 204 Vs 404

I have 2 resources User and Album. A user has a list of albums. To get albums there are 2 REST API.
user/{userId}/albums/{albumId} gets album by albumId. If not found returns 404
user/{userId}/albums gets all albums by userId. In this case, if a user has no albums, what should be the status code 204 or 404?
Is the absence of any album really seen as an error? Assuming the albums are returned as a JSON array, the common response to such a situation would be a HTTP 200 with an empty array as the body.
Returning 404 signals that the resource doesn't exist, kind of saying that it isn't even possible to ask for the list of albums for this particular user. But in fact, it's possible to successfully return the list of albums, it's just that the list is empty. It doesn't seem at all exceptional to me. This is completely in contrast to retrieval of one specific album using an ID that doesn't exist (using your other endpoint); in such a situation a 404 is correct.
While a 204 seems better than a 404, because it at least tells the client that the request was successful but had no content, its intention is not really to be used to signal a "successful absence". Rather, it signals that the resource DOES exist but for some reason the server chose not to include the resource in the response body - for example the purpose of the request could have been to simply pass back some headers to the client.
A 204 can also be used as a response to a POST request where some action was carried out by the server without necessarily creating any new resource (which would have implied a 201 CREATED), or where it's for some other reason not relevant to return any resource.
I think it's clear that what you need is a
GET /user/xxx/albums
HTTP/1.1 200 OK
[]
Here is what the RFC2616 that defines the HTTP protocol says about Status-codes:
The first digit of the Status-Code defines the class of response. The last two digits do not have any categorization role. There are
5 values for the first digit:
- 1xx: Informational - Request received, continuing process
- 2xx: Success - The action was successfully received,
understood, and accepted
- 3xx: Redirection - Further action must be taken in order to
complete the request
- 4xx: Client Error - The request contains bad syntax or cannot
be fulfilled
- 5xx: Server Error - The server failed to fulfill an apparently
valid request
In your case, the request was successful, but there are no albums to show, so you definitely should use a status from the 2xx category.
Here is what the RFC says about the 204 status:
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. 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.
The RFC states that the 204 is primarily intended to allow inputs, so you shouldn't use this one. I would use the 200 in this case.
Error Code 404
The web site hosting server will typically generate a "404 Not Found" web page when a user attempts to follow a broken or dead link.
Return Code 204
The server has fulfilled the request but does not need to return an entity-body.
Conclusion
You obviously need to return a 204 status code. If you use the 404 one, the user may be disturbed. More, you use 404 when the targeted album doesn't exist. Using 404 for both 1 and 2 is illogical.
When you ask for a specific resource, say a user, and the user doesn't exist, then you should return 404. For example, you have an API to retrieve a user using the following URL:
https://yourdomain.com/api/users/:userid
and a request is made to retrieve user 1234, that doesn't exist, then you should return 404. In this case, the client requested a resource that doesn't exist.
https://yourdomain.com/api/users/1234
404
Now suppose you have an api that returns all users in the system using the following url:
https://yourdomain.com/api/users
If there are no users in the system, then, in this case, you should return 204.
Let me give my 2 cents on this. I hope you already know the difference between 404 vs 204.
The scenario i would prefer to use each status code are :
404 Status Code
404 means that the Resource not found or doesn't exist or URL is invalid
For example
GET : https://api.myapp.io/product/product_id_123
GET : https://api.myapp.io/image/nokia.jpg
If the single product / resource item doesn't exist in database or in resource folder, that means the resource of this URL is invalid so we have to throw 404 and Search Engines like Google & bing will not going to cache the result and will not retry again the next day for fresh content.
204 Status Code
204 means that the URL is valid and Server has successfully did the execution but it has no data to return.
For example
GET : https://api.myapp.io/product/search?keyword=nokia
If there is no data matched (single or multiple) for the keyword in database to return back the results, then throw 204 because there is no data to return but the URL is still valid and Search Engines like Google & bing will retry again the next day for fresh content because for them it is not invalid url and when you retry the next day there might be some data which matches the query.
I agree with the responses, but I think is 204 or 200, it depends of your response when the album list is empty.
If you will return a empty array, the return it with 200 code, if you prefer to don't return anything, then the right one will be 204. (I prefer a 200 with empty list)
Only use 404 with a resource doesn't existis, if it is a empty list the choose 204 or 200.
Good hacking man!