I am about to implement a REST api. I want to know what's the difference between HttpStatus.OK and HttpStatus.ACCEPTED:
return new ResponseEntity<User>(u, HttpStatus.OK));
And
return new ResponseEntity<User>(u, HttpStatus.ACCEPTED);
As per Spring documentation given on this link
HttpStatus.OK
200 Ok means The request has succeeded. The information returned with the response is dependent on the method used in the request
HttpStatus.ACCEPTED:
202 Accepted. means The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
for More information on HTTP response Status Code Definitions please visit this link
Related
For some security reason, we have added a common spring filter that perform a cross-cutting check and drop a 403 when a security rule is broken.
The solution is working fine in case of synchronous endpoint (i.e. returning a ResponseBody<SomeDTO>)
However, we have several asynchronous endpoints which return ResponseBodyEmitter.
If (checks == false){
// Then the filter should erase the response body and override the http status to 403.
}
For asynchronous method,the checks are performed during the response sending.
Hence the endpoint may send at the beginning 200 with a response body and then drops the connection with 403 and empty body.
Question:
From design wise, is this behavior coherent with REST ? (i.e. OK OK OK and then FORBIDDEN)
A HTTP request can only return 1 HTTP response, so "OK OK OK and then FORBIDDEN" is not actually possible. So REST doesn't care if you have some internal state that defaults to 200, eventually becomes 403 and then the last one gets sent back to the client. HTTP and REST doesn't know what goes on in your server leading to that 403.
However, if you have some mechanism that does permission checks after processing the entire request, and if the user doesn't have permission it erases the response body and sets a 403 response, that only seems reasonable for safe methods (e.g.: read-only methods like GET).
I have a HTML form, which I submit via http post.
There are two cases:
Case 1: The data is valid and data on the server will be updated accordingly
Case 2: The data is invalid and the http response contains an error message for the user.
Which http status codes should be used for each case?
I use htmx to submit the form. This means I don't need to use the POST/Redirect/GET pattern.
This question is not about JSON-APIs.
The complete list of HTTP response codes published by the Mozilla Foundation is pretty comprehensive and easy-to-read, so I'd recommend always consulting it as a guide. For the generic use-cases mentioned by you, there are a couple of different codes you can return - depending on what happens with the data on the server, and what you want to happen in the user's browser.
CASE 1: data is valid, data on server is updated
Base on your short description, the different status codes that might be applicable are:
200 (OK): you are updating an existing record on your own server - eg., the user is submitting a form which updates their existing contact information on your website - and information was received, and the record updated successfully. The response would usually contain a copy of the updated record.
201 (Created): you are not updating an existing record, but rather, creating a new record on your server - eg., your user is adding a new phone number to their contact details, which is saved in your database as a separate 'phone' record. The response should contain a copy of the newly created record.
205 (Reset Content): the same as 200, but implies that the browser view needs to be refreshed. This is useful when the record that is being updated has values that are dynamically calculated by the server, and which might change automatically depending on the values you're submitting. For example, if you have a user adding extra information to their online profile, which might grant them special status, badges and privileges on the website. This means, that if the user is viewing their profile information, that information will need to be updated with the new 'status' automatically granted by the server. The 205 response body will normally be empty, which means that to update the browser view your response-handling code will need to:
do further ajax requests and update the relevant part(s) of your
interface with new information from the server, or
redirect the user to a new URL, or
reload the entire page.
If working with HTMX, a 200 or 201 response would include the actual html snippet of the record that you want updated on the page - and HTMX will replace it automatically for you when it receives the response. With a 205 response, you could send an HX-Trigger response header that would call a custom event on the interface elements that need to update themselves - see the examples in the docs.
CASE 2: data is invalid, data on server is not updated
The status code that needs to be returned in case of an error varies depending on what caused the error. Errors that the server believes are the responsibility of the client - such as 'sending invalid data' - have a status code in the 4XX range. Some of the common errors in that range include 404 ('Not Found'), 403 ('Forbidden'), and 'Unauthorised' (401).
In the case of a client sending data that the server cannot process because it is 'not valid' - either because the request itself is malformed, or because the data doesn't pass some business validation logic - the current advice is to return status 400 (Bad Request).
Many years ago, some people believed that the status code 400 should only be used to indicate a malformed request (syntactical error) - not to indicate a failure in business validation logic (semantic error). There was a lot of debate, and temporarily a new status code (422) was created, that was supposed to cover semantic errors, exclusively. In 2014, however, the official definition of the status 400 code was changed to allow for the inclusion of both syntactical and semantical errors - which rendered status 422 essentially unnecessary.
You can find lots of discussions and explanations online about the differences between 400 and 422, and some people still argue passionately about this to this day. In practice, however, the 400 code is all you'll need - and you can include a response body in it that explains in detail, if needed, the cause of the error.
Note that when working with HTMX, a response with a 400 code should trigger an htmx:responseError event automatically. You can trap that event, for example, to update your form interface elements, in case of data validation errors caught by the server.
Well, 200 OK and 201 Created are the best for successful result.
For invalid data I would return 422 Unprocessable Entity, because the headers are correct, but body is not (though parseable by the server). The caveat is some HTTP clients won't handle 422 properly and in this case you have to use 400 Bad Request, however, the most of the modern clients will be fine.
You have said it is not about JSON APIs, but how will you meet this type of requirement - it is not clear whether this is relevant for your scenario???
SERVER DRIVEN BEHAVIOUR
I cannot see how a client could ever decide an HTTP status code based on input data. How would the client deal with these examples?
The call is not authenticated (cookie or token) - an API would return 401 - this tells the UI to perform a retry action.
The call is not authorized - an API would return 403 or 404 and the UI would present an error display.
The data is malformed or invalid according to domain specific checks - an API would return 400 and tell the UI what is wrong so that it can perform actions.
Something went wrong in server processing, eg data cannot be saved because database is down.
MY THOUGHTS
htmx looks interesting but a key requirement before using it would be ensuring that htmx can read server side error responses and use values returned. Maybe there is an elegant way to do this ...
Maybe I am just paranoid :). But it is worth being careful when choosing technologies that there are no blocking issues. Lack of error handlng control would be a blocking issue in most systems.
I'm using htmx 1.8 with asp.net core 6.0.
This works for me.
controller:
//server side validation failed
Response.StatusCode = 422;
return PartialView("Core", product);
client side javascript:
document.body.addEventListener('htmx:beforeOnLoad', function (evt) {
if (evt.detail.xhr.status === 422) {
//
// allow 422 responses to swap as we are using this as a signal that
// a form was submitted with bad data and want to rerender with the
// error messages
//
evt.detail.shouldSwap = true;
evt.detail.isError = false;
}
});
200 OK or 201 Created are the best choice for a successful POST request.
However, for invald data, you can pass 415 Unsupported Media Type
I have 2 Spring-Boot-Reactive apps, one server and one client; the client calls the server like so:
Flux<Thing> things = thingsApi.listThings(5);
And I want to have this as a list for later use:
// "extractContent" operation takes 1.5s per "thing"
List<String> thingsContent = things.map(ThingConverter::extractContent)
.collect(Collectors.toList())
.block()
On the server side, the endpoint definition looks like this:
#Override
public Mono<ResponseEntity<Flux<Thing>>> listThings(
#NotNull #Valid #RequestParam(value = "nbThings") Integer nbThings,
ServerWebExchange exchange
) {
// "getThings" operation takes 1.5s per "thing"
Flux<Thing> things = thingsService.getThings(nbThings);
return Mono.just(new ResponseEntity<>(things, HttpStatus.OK));
}
The signature comes from the Open-API generated code (Spring-Boot server, reactive mode).
What I observe: the client jumps to things.map immediately but only starts processing the Flux after the server has finished sending all the "things".
What I would like: the server should send the "things" as they are generated so that the client can start processing them as they arrive, effectively halving the processing time.
Is there a way to achieve this? I've found many tutorials online for the server part, but none with a java client. I've heard of server-sent events, but can my goal be achieved using a "classic" Open-API endpoint definition that returns a Flux?
The problem seemed too complex to fit a minimal viable example in the question body; full code available for reference on Github.
EDIT: redirect link to main branch after merge of the proposed solution
I've got it running by changing 2 points:
First: I've changed the content type of the response of your /things endpoint, to:
content:
text/event-stream
Don't forget to change also the default response, else the client will expect the type application/json and will wait for the whole response.
Second point: I've changed the return of ThingsService.getThings to this.getThingsFromExistingStream (the method you comment out)
I pushed my changes to a new branch fix-flux-response on your Github, so you can test them directly.
I know someone who is writing an API, and wants to use HTTP status codes to report the outcome of queries. e.g. if the user calls example.com/api/product_info?product_id=X, and the product doesn't exist, it would return HTTP status 400: Bad Request. I think that, since this is a valid call (i.e. the actual HTTP request is not malformed), it should return a 200 code response, and just have the body of the response something like {status: 'error'; message: 'No such product'}.
So my question is,
1) Is it appropriate to use HTTP status codes to convey non-HTTP program state, as in the example above?
2) Is there some standard, or at least widely used, specification describing when HTTP status codes are appropriate for use?
I was actually just talking about this the other day - http://blogs.mulesoft.org/api-best-practices-response-handling/
Your status code should reflect the response of the API, as 200 is "OK" and should be used for data that is successfully returned. However, 201 should be used for created items.
As mentioned already, in the event where the user tries a call but it fails (ie: users/?id=5) the server could return back a 400 to inform the user that it was a Bad Request, or a 404 if the resource doesn't exist.
It also depends on the action - if they are searching for a user and there are no responses, I wouldn't return an error, just a 200 with no results found. However, if they are trying to do a PUT or PATCH on a user that doesn't exist I would tell them with an error- as chances are there's a problem within their application somewhere.
In the link posted above you'll find more status codes, but one of the biggest advantages to using status codes is that it informs the client just though the header what actually happened with the server. This allows them to do a relatively quick (and low memory) check instead of having to deserialize the body and loop through an array looking for an errors key.
Essentially, you're giving them the tools to quickly and easily understand what is happening- something that I think every (sane) developer appreciates.
Hope this helps!
- Mike
While running Jmeter scripts, one of the step is failing but Successful Result is coming in Sample Result as:
Sample Count: 1
Error Count: 1
Response code: 200
Response message: OK
But error message is coming in Response Data as:
Unfortunately, we could not delete your entire itinerary because of a database synchronization error.
If you could please re-load your itinerary and try again, we would appreciate it.
Thank you for your patience.
I need to re-submit the Request for that i am using the While loop comparing the Response Data then try to resubmit the request which is not working as.
if(ResponseData.equals("Unfortunately")==true)
{
log.error("Database synchronization error...Re sending Request");
vars.put("resubmitflag","true");
}
The problem i believe that i am not using correct functions for it as
ResponseData.equals will not work as how we can compare whole response data
which is not possible.
Kindly anyone help how to proceed and what functions need to use for that.
If you're talking about Beanshell Post Processor, there are a couple of issues with your code.
ResponseData isn't something, which is available to Beanshell Post Processor. You need either use data (which is byte array previous sampler response representation) or prev (which stands for SampleResult class for previous sampler).
equals method checks 2 strings for being identical. In your case you need to consider either startsWith or even contains method.
See following code samples for reference
String response = new String(data);
if (response.contains("Unfortunately")){
log.error("Database synchronization error...Re sending Request");
vars.put("resubmitflag","true");
}
or
String response = prev.getResponseDataAsString();
.....
See How to use BeanShell guide for more details.
Hope this helps