im writing a java application that sends a post request to a server and expect a json from the server. Now when i need to get the response from the server do i only need to get it from the inputStream when the http code is 200 (HTTP OK) or is there any other cases ? , example :
//...
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
// only here try to get the response
}
//...
It depends on how the server is implemented. Check the API, if the server has one. If it's internal, ask your server guy.
Generally speaking, if your response code is either 2xx or 3xx, I would check the response anyway...
If the server your communicating with is following the spec then either 200 or 201 responses are valid to contain an entity. A 204 response is successful but has no data in the response.
See section 9.5 here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 for details of acceptable responses to a POST. Extract below:
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).
There are three things to consider:
All 2xx codes denote success of some sort. But depending on the exact code, your reading code might be different. (204 for example means success but no content.)
There are redirecting codes (3xx). These are usually automatically followed by the http client library but you can also set them not to, in which case you need to have custom code that handles these cases.
There can be valuable information returned in the stream even if you get a code that denotes an error. Whether you want to process it depends on your exact needs.
Related
I have a REST service which is a POST to create a user, if the user does not exist, the user is created, and the service returns a 200 with the user in a json format.
Case 1: What if the user exists already, do I return a functionnal exception, so a json containing an error (all of this managed by the error handling of spring boot), and what about the http status code
Some people say to send a 303 or a 409 ... many different answers, and what about the response body in that case?
Case 2: What if in the backend we have let say a rule on the name (like containing a space) which returns an error (space not allowed in a name), same questions, do i have to return a functionnal exception and what about the http status code in this case
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
It all depends on how one interprets the various http status codes and how user friendly do you want your HTTP payload responses to be. Below are few suggestions:
NEW USER CREATED : If its a new user and gets created successfully in the backend then you return http status code 201. This is a technical status code. You can also return a functional status in the response body mentioning "User created"
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
USER ALREADY EXISTS : If the user already exists, you should respond with http status code 200 with a response payload body mentioning a functional status "User already exists"
USER CREATION FAILED : If the new user rules are not satisfied at the backend service and it throws an error then the http status code of 400 can be used and functional status in response payload of "User creation failed, please conform to the user name rules" https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
For an API Consumer to know everything about your API's, you may want to provide a API specification document. You may use open API spec(previously known as swagger) https://swagger.io/specification/
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
Not quite.
The HTTP status code is meta data in the transfer documents over a network domain. It communicates the overall semantics of the response (for instance, is the body of the message a representation of a resource, or a representation of an error? is this response cachable? and so on).
For unsafe requests in particular, cache invalidation is sensitive to "non-error status codes". The difference between 303 (non-error status code) and 409 (error status code) can be significant.
The Content-Type header gives you a mechanism to describe the kind (schema) of the message you are returning (ex: application/problem+json).
The way I think about it: the information for your bespoke consumer belongs in the message-body; we lift data from the message-body to the HTTP metadata so that general-purpose components can take advantage of that information (for example, by invalidating cache entries).
So we would normally start by defining the schema and semantics of the message body, and making sure that we have intelligent ways to communicate all of the things we want the caller to know. In other words, we are defining the documents that we pass to the client, and how to extract information from them.
Information that HTTP components need to know get copied from our bespoke document into the standardized forms (status code, headers).
Where things get complicated: the fact that something is an "error" in your domain, that doesn't necessarily mean that it should also be considered to be an "error" in the transfer of documents over a network domain.
A common case: we are using our API to navigate some work through a process; that process has a happy path, and also some exceptional paths that we normally try to avoid (accounts are overdrawn, items are out of stock, etc).
An HTTP request can move work from the happy path to an exception path and still be a "success" in the transfer of documents domain.
The easiest heuristic I know is to think about previously cached copies of responses by the same target URI. If those responses are still re-usable, then you are probably looking at a 4xx status code. If the responses should be invalidated, then you are probably looking at a 2xx or 3xx status code.
I need to write an API to check if a user name already exists in a database.
I want my server (Struts Action class instance in tomcat server) to return true/false.
Its something like this
checkUserName?userName=john
I want to know what is the standard way to do this?
Shall I return a JSON response with just one boolean value ... seems like a overkill.
Shall I do something like manually setting the HTTP header to 200 or 404 (for true/false), but that seems to violate the actual purpose of using the headers which I believe must only be used to indicate network failures etc.
(Too long for a comment.)
I don't see any reason not to return a standard JSON response with something indicating whether or not the user name exists. That's what APIs do: there's nothing "overkill" about providing a response useful across clients.
To your second point: headers do a lot more than "indicate network problems". A 404 isn't a network problem, it means the requested resource doesn't exist. It is not appropriate in your case, because you're not requesting a resource: the resource is checkUserName, which does exist. If instead your request was /userByName/john a 404 would be appropriate if the user didn't exist. That's not an appropriate request in this case, because you don't want to return the user.
A 401 isn't a network problem, it's an authentication issue. A 302 isn't a network problem, it's a redirect. Etc. Using HTTP response codes is entirely appropriate, if they match your requests.
I am studying how to Spring handle REST web services (but I don't know if it is a Spring related answer or more generically it is related only to REST concept).
So my doubt is: what exactly is the HTTP status return code for a successful DELETE statement?
Is it the 204 or the 200?
I know that the 200 means that my request was correctly fulfilled but reading online it seems to me that it I expect it after a successful GET returning content and not after a delete.
Somewhere I found that the 204 status is obtained after
successful PUT or DELETE. Is it true? I can't understand, it means that the response is empty, why an empty respons means that the PUT or the DELETE operation are gone succesfull?
There are no strict rules on which HTTP status code is the correct one for each method. It depends on what exactly happened, what information you need to send to the client, etc. I can think of a few examples:
A successful DELETE, with no further information. 204 No Content
A successful DELETE, but you have a warning about related orphan resources that should be deleted too. 200 OK.
You accepted the DELETE request, but it might take a long time and you're going to do it asynchronously. The client should check it later. 202 Accepted.
You accepted the DELETE request, but the resource can't be removed and the URI is instead reset to a default. 205 Reset Content.
An empty response body doesn't mean that a delete is successful, a successful delete (usually) means that the response body is empty.
There's no official status code list for RESTful APIs, but most agree that a 204 is a good response code for a successful delete, as there's usually not a good reason to return a response body after deleting something.
In general, if an operation is successful and the response body is empty return 204. If an operation is successul and the response body is NOT empty, return 200
An empty response doesn't mean the operation was successful, the HTTP error code is supposed to indicate success/failure, and the response body may or may not contain data.
The response body may contain additional information regarding the request, e.g., a specific message to display to the UI, stats or timing info regarding the information, whatever. But it doesn't have to, and the body's purpose is informational/diagnostic if it exists.
2xx represents the request was successful. The xx just allows for you to be more specific about what happened (what the server did or is returning).
Is it possible to send HTTP POST request to a webserver and retrieve just headers of response or read just few bytes of the body, so the rest won't be downloaded at all (so it won't consume traffic)? If yes, how?
I know that there is a HEAD method for this, but I need to achieve it by POST method .. well, I am not sure if I need the POST method, I just need to post the data. Maybe if the webserver isn't secured well enough (it doesn't check what method it's used - it's just directly access the post data), is it possible to send "post data" by HEAD request?
There is no built-in HTTP mechanism for this, and HTTP HEAD requests do not allow content in the body. If however you are the one writing the server code then anything is possible.
If this is the case, I would suggest a URL parameter that triggers this behavior. For example:
POST /myURL - This would return the whole response
POST /myURL?body=minimal - Returns the reduced size response that you are looking for.
And you would have to code your server method to construct and return the appropriate response based on the URL parameter.
I am using RESTlet and I have created a resource. I handle POST by overriding acceptRepresentation method.
The client should send me some data, then I store it to DB, set response to 201 (SUCCESS_CREATED) and I need to return some data to the client, but return type of acceptRepresentation is void.
In my case, I need to return some identificator so that client can access that resource.
For example, if I had a resource with URL /resource and the client sends POST request I add a new row in DB and its address should be /resource/{id}. I need to send {id}.
Am I doing something wrong? Does REST principles allow to return something after POST? If yes, how can I do it, and if no what is the way to handle this situation?
REST just says that you should conform to the uniform interface. In other words, it says you should do what POST is supposed to do as per the HTTP spec. Here is the quote from that spec that is relevant,
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).
As you can see from this, you have two places where you can indicate to the client where the newly created resource resides. The Location header should have an URL that points to the new resource and you can return an entity with the details also.
I'm not sure what the difference between overriding acceptRepresentation() and overriding post() but this example shows how to return a response from a POST.
I'd forgo sending anything in the body of the response. Just set Location: to the (full) URL of the newly created resource.
Your description suggests that this is exactly the semantics you:
POST a thing to create it
Respond with enough to know two things:
That the creation happened (the 201)
Where to find the new thing (the Location header)
Anything else is superfluous.
Two different questions:
Does the REST application pattern support returning data in a POST?
I don't think REST explicitly disallows it, but the preferred treatment is spelled out in Darrel's answer.
Does the RESTlet framework allow returning data in a POST?
Yes, even though it returns void, in a class which extends Resource, you have full access to the Response object object via the getResponse() method. So you can call getResponse().setEntity() with whatever data you want.
Output it in whatever format is requested. That might be:
<success>
<id>5483</id>
</success>
Or:
{ "type": "success", "id": 5483 }
It depends on what you usually do. If they're not expecting the data, they should just ignore it, but any client that wants to handle it properly should be able to.
If you respond 201 Created with an entity body, rather than a Location redirect, then it's a good idea to include a Content-Location header pointing to the resource that is being represented in the response.
This will avoid potential confusion - in which a client could (justifiably) assume that the response entity actually represents a new state of the 'creator', and not the created resource.
> POST /collection
> ..new item..
< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>