I'm new to the .NET web api. But I can't figure out what the best practice should be when returning status codes. I've followed the tutorial on creating a web api that supports crud operations to get a good idea on how it all works.
I have a spec where the response to every request returns a status code along with other data, I can change the spec if need be but I can't work out if it's good to return a status code and also return all the data requested or to just return the data on it's own.
For example if I made a request to GetAllCarManufacturers without being authenticated I'd return a custom statusCode of 1 (Indicating not authenticated), and message "User is not authenticated.". But if I was authenticated I'd like to send back a statusCode of 0 (indicating success) and all the car manufacturers. This seems to go against the way the tutorial is organised as only the car manufacturers are sent back without any additional data. Which leads me to believe passing around a statusCode isn't the correct thing to do.
I've seen in the example crud demo that HttpResponseExceptions are thrown which sets the HttpStatusCode to a certain value (see code below). Should I be using that instead of returning my own status code? But then my concern is it doesn't have enough different status codes that will match my custom scenarios.
// Setting the HTTPStatusCode example.
throw new HttpResponseException(HttpStatusCode.NotFound);
.NET Web API sets up a convention for HTTP calls to a server that supports a REST interface. So, if you follow the convention, you should return HTTP Status Codes as a way of indicating what happened to the request when the server processed it.
HTTP Status Codes are part of the HTTP spec and can be found here.
There are many benefits to using HTTP Status Codes. One is that the HTTP Status Code is a header, so the client doesn't have to look into the content of the response in order to find out what happened.
So, returning a custom status code (of say 0 or 1) is not very useful to HTTP clients if they expect a RESTful experience from your interface.
Related
I've a scenario where a post request from first microservice creates new user and creates a wallet for newly created user from different microservice.
I'm returning HTTP status 201 when both user and wallet created. I'm bit confused what status should I return if user is created but wallet isn't.
I came across some articles and found two relevant to my confusion but are contradictory on returning HTTP status 207 due to its limitation related to WebDAV.
Is Http response 207 MULTI-STATUS appropriate for multi task operations?
REST API response in partial success
refer my code -
#PostMapping("/register")
public ResponseEntity<User> saveUser(#RequestBody User user) {
user.setUserId(sequenceGeneratorService.generateSequence(User.SEQUENCE_NAME));
user.getRoles().forEach(role -> role.setRoleId(sequenceGeneratorService.generateSequence(Role.SEQUENCE_NAME)));
User savedUser = userService.saveUser(user);
ResponseEntity<Wallet> createdWallet = createUserWallet(savedUser);
if (createdWallet.getStatusCode().is2xxSuccessful()) {
savedUser.setWallet(createdWallet.getBody());
return new ResponseEntity<User>(savedUser, HttpStatus.CREATED);
} else {// here is the confusion
return new ResponseEntity<User>(savedUser, HttpStatus.MULTI_STATUS);
}
}
private ResponseEntity<Wallet> createUserWallet(User savedUser) {
Wallet userWallet = Wallet.builder()
.walletId(sequenceGeneratorService.generateSequence(Wallet.SEQUENCE_NAME))
.userId(savedUser.getUserId())
.balance(BigDecimal.ZERO).build();
return walletServiceProxy.createWallet(userWallet);
}
May I know which status should I return here?
I'm returning HTTP status 201 when both user and wallet created. I'm bit confused what status should I return if user is created but wallet isn't.
HTTP status codes are metadata of the transfer-of-documents-over-a-network domain (see Webber 2011); they are there so that general purpose HTTP components can correctly interpret the response, and do intelligent things (like invalidating previously cached responses, when appropriate).
Your HTTP API is a facade: a costume that your implementation wears that makes it look like an HTTP aware document store. (The fact that your implementation doesn't have "documents" is an implementation detail, hidden behind this facade.)
The responses you send should be understood in this same way - you are telling the HTTP client (and also any intermediary components who can read the response metadata) how your (imaginary) web page reacted to the request that was sent.
Was the message processed successfully? Did it create a new (imaginary) web page with its own identifier, that clients can send messages to? Then you should normally be sending back a 201 Created, even if the implementation didn't achieve that outcome via the "happy path".
On the other hand, if you want general purpose components to understand that request processing failed, you send a 4XX Client Error or a 5XX Server Error, as appropriate.
(You probably shouldn't be using 207 MultiStatus unless you are deliberately doing WebDav things and are expecting requests from WebDav aware components; it doesn't achieve anything useful unless the client implementation knows how to handle multistatus XML documents).
Reminder: the part of an HTTP response where you describe in detail what happened and how the end consumer can respond to it is the body of the HTTP response.
201 Created
Location: /users/12345
Content-Type: text/plain
Hey, we created the new user you asked us to. Isn't that great?
You can review the details of the user at: /users/12345
But, we weren't able to create a wallet for the user. If that's
kind of important to you, could you fill in this form and send it
to us: /lost-wallets#form ?
Thanks, and have a great day
I'm trying to design an endpoint that just does some loggings for the client-side applications. The implementation is simple, just log the events that the client send to some platforms. (We don't want the mobile app to integrate with the platforms directly) If the client doesn't care about the response and won't handle the response either, is there a need for the server to send back the 200 all the time? Or is it okay to just return nothing?
I can't seem to find any similar use cases. Maybe giving a status code is always a good practice?
I'm using sprint boot and the controller allows the return type of void.
If this is your product and you're not beholden to any other API expectations or other miscellaneous requirements, you can implement whatever behavior you'd like.
That said I can understand wanting to stick to best practices. In general if the response is going to be empty, a simple HTTP status code of 204 is typically the best option to conform to standard HTTP status codes.
I have written a REST API in nodejs.
I want to send HTTP status codes on various events.
For example when data is returned I send HTTP code 200.
What is the status code to return when the input data is missing?
This isn't specific to nodejs. HTTP status codes are general -- you can read about them on wikipedia:
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
I think you want client error code 400, which means Bad Request.
Perhaps you should return 404, not found. As mentioned in previous answer, HTTP status codes are general.
A tip: try getting grip on HTTP before starting off web development.
When constructing an API response, which method is better for (manually) returning the status code to indicate the validity of the request:
1 - Embed a response code within the JSON response
{
'status_code' => 200,
'status_message' => 'OK',
'data' => { ... }
}
2 - Or is it better to modify the HTTP Headers Status field?
Request URL:http://somesite.com
Request Method:GET
Status Code: 200 (EDITING THIS ONE)
I would think that the HTTP Statuses should only be regarding connection errors and file retrieval errors that occur at the server level rather than altering this to address application level errors.
Any good articles and resources to read would be very appreciated as well.
I have found the best way to present errors in a REST Request is to change the HTTP Status Code to the proper error, and embed the error in the response.
If you are using JSON, it might look like this, with the status code set to 500 for this example:
{"error" : "An error has occurred while trying to read from the database."}
This is the same method that Microsoft CRM uses to report errors, and it has proved to be a good method; RESTFul applications will not fail to parse the response if they are expecting JSON (or XML, if you are using that).
This question addresses the same issue (perhaps from a slightly different perspective).
I think that, in general, if a request to a resource in your application results in an error condition, that fact should be reflected in the HTTP headers. You can use the application response to provide more detailed information.
Update: Here is an interesting mapping of application errors to status codes (used by Azure).
When communicating with our REST webservice, an http response with status code of 304 is returned to indicate that the resource requested hasn't changed. However our WP7 application, using the HttpWebRequest class, the phone is taking exactly 2 minutes before this type of response is successfully read.
HttpWebRequest request = HttpWebRequest.Create("path/to/unchanged/resource") as HttpWebRequest;
request.Method = "GET";
request.BeginGetResponse(
new AsyncCallback(
(aysncResult) => {
// response is read correctly here... 120 seconds later
}), null);
I can see that the webservice is responding immediately with 304 and no body data, the request itself is not timing-out and our application is able to successfully handle other response codes [404, 201 etc]. Could it be a Silverlight browser "caching" issue?
Can anyone confirm that they've seen this before, or have any thoughts on the issue?
Cheers,
Alasdair.
== Additional Information ==
As a result of WP7 restricting certain request headers, we use a custom [If-Modified-Since] header for all our resource requests. This custom header [X-If-Modified-Since] is recognised by the firewall in front of the webservice and modified back to the standard header. I'm unsure if this is related to the issue described above.
Answered my own question in case anyone is interested or facing a similar problem.
We eventually created a work around by configuring our webservice to respond with an OK (200) http status code, and writing the actual response code in a custom header X-Http-Status. On the client side when we parse the response, if this custom header exist then we take this to being the actual status code and continue with the business logic from there.
This allows us to potentially deal with any additional status codes that the Windows Phone handles differently.
The cause of the issue is still unknown, although we strongly suspect that since this is a NOT MODIFIED (304) code, some caching is happening at some low level layer in Silverlight before the response is made available to us.