I am wondering what the "default" response from a "DELETE /api/myEntity/1" request is RestKit expecting.
My current web service returns OK (200) status code with empty body. Meaning that the object was successfully deleted.
RestKit triggers the onDidFailWithError method, and also logs some messages to the debug output:
restkit.network:RKObjectLoader.m:300 Unable to find parser for MIME Type 'text/plain'
restkit.network:RKObjectLoader.m:329 Encountered unexpected response with status code: 200 (MIME Type: text/plain ->
The web service is developed by us. So we can return anything else, we just think returning "OK" is enough.
Please advise. Thanks.
For all empty responses the correct status code to be returned should be 204 No Content.
RestKit declares to correctly handle also 200 OK but I experienced some problem with delete, too.
I found some bux fixes done after tag v0.10.3 (see here) so I suggest you to upgrade to a more recent commit.
Be careful to update to newer v0.20 because it is an hard refactoring and a lot of things were changed!
Related
this is a question related to good practices in signalling the communication between various APIs in a Microservice architecture.
I am facing the following 'events':
one Microservice is DOWN (physically)
one Microservice is calling another one using a wrong URL
one Microservice is calling another one using a correct URL but wrong arguments (query params for example, or POST body fails validation)
one Microservice is asking another one for a resource and that particular resource cannot be found in DB (lets say a findById type)
I need to find a better way to signal these by using HTTP Status codes and various payloads explaining in detail what's going on.
For example:
for case 1, I could use NOT_FOUND (404) with a payload: API_DOWN
for case 2, I could use BAD_REQUEST (400)
for case 3, I could also use BAD_REQUEST (400) with a validation payload message
for case 4, I could also use NOT_FOUND (404) with a RESOURCE_NOT_FOUND message
everything else could be INTERNAL_SERVER_ERROR if caused by a uncaught exception.
200 OK for good stuff
Any thoughts? I am not 100% happy with my interim solution. Want to make it better. I understand the fact there are 2 animals here: one is client-server signalling and second one is related to data (payloads missing etc)
one Microservice is DOWN (physically) - I could use NOT_FOUND (404) with a payload: API_DOWN
In this instance you will have no control over what response code the consumer receives. Depending on how the service is hosted and managed, you may receive any of 500 Server error, 502 Bad gateway, 503 Unavailable, or 504 Timeout. However, what you will get depends on your infrastructure and stack set up.
one Microservice is calling another one using a wrong URL - I could use BAD_REQUEST (400)
This is semantically identical to the above case. There is very little difference between trying to call a service which is unavailable, and trying to call one which doesn't exist.
one Microservice is calling another one using a correct URL but wrong
arguments (query params for example, or POST body fails validation) - I could also use BAD_REQUEST (400) with a validation payload message
There are a couple of variants of this. One is calling PUT on a resource which only supported PATCH, for example. In this instance there is a status code for this, it's 405 Method not allowed. Again, you're usually not in control here - most service frameworks will automatically return this status code to consumers if you do not define a requested operation against a given resource.
Another variant (as in your example) is incorrect query parameters. Again most frameworks will automatically return 400 Bad request (or 422 Unprocessable) in this instance. If the query parameter is provided but is invalid in some other way, then 400 Bad request is appropriate.
Note: it is not generally appropriate to return a 400 Bad request for an "invalid" path parameter.
one Microservice is asking another one for a resource and that
particular resource cannot be found in DB (lets say a findById type) - I could also use NOT_FOUND (404) with a RESOURCE_NOT_FOUND message
Yes, 404 Not found is the correct status code.
everything else could be INTERNAL_SERVER_ERROR if caused by a uncaught
exception.
Not necessarily. One status code I use often is 409 Conflict for those instances where the input is OK but has caused some kind of problem (like duplicate entities).
200 OK for good stuff
200 is fine in many situations. However, consider 201 Created if something has been added, 202 Accepted if the call had no effect (like if you try to create a resource but the resource was already there), or 204 No Content if you want to explicitly call out that no return type should be expected.
Just a small addition what #tom-redfern already said.
There's a nice map i like. Looks like a plan for an underground.
HTTP Status Map by Restlet
On the bottom right side of the image you have nice summary.
Code 100: Informational
Code 200: Success
Code 300: Redirectional
Code 400: Client Error
Code 500: Server Error
You can hover the status codes and get a nice and short explanation to it. Maybe this helps you for your implementation.
For example we got multiple times the same request nearly at the same time. This lead to duplicate entries in our elasticsearch. We added a servlet filter which catches duplicates and returns a 409 CONFLICT status code.
Description for 409 is in example:
Indicates that the request could not be processed because of conflict
in the request, such as an edit conflict in the case of multiple
updates.
not really sure where to start here other then to dive into CF (I REALLY don't want to do that) but....
I have an NSURLConnection signing OAuth2 requests to an ASP.NET WebAPI Resource Server, this resource server returns JSON body AND statusCode 400. I have yet to find a way to parse the data from the response when it returns code 400.
Does anyone here have any ideas? I would prefer to keep using NSURLConnection as this is only an OAuth2 consumer class. My other code is using restkit, but I do not want the OAuth2 end to require said library.
The process to parse data from a request which returns status 400 should be identical to that of a request returning status 200.
Simply note the status code in -connection:didReceiveResponse: and allow the request to continue; you will receive any additional data that the server sends in -connection:didReceiveData: as usual. Finally, you'll get a -connectionDidFinishLoading: call when all data has been received, and you can parse the JSON there.
Does your HTTP request Accept header specify "application/json"? If so, then this is probably an IIS bug and not iOS.
Interestingly enough, MVC4 ActionResult is broken in the RTM. Switching it over to Pure WebApi and fine tuning the response, I was able to finesse it into returning the proper data, it was likely serializing the json improperly which other languages weren't catching.
I have a project set up using ASP.NET WebAPI on top of Azure, and am having a problem whenever I try to make an HTTP Post where the content-length is too long in the header.
Normally I would've just ignored this problem, because you should be correctly setting the content-length on POST, but it turns out that when this happens, it causes the session to hang indefinitely, and then the Azure emulator crashes.
I have a custom JSON Formatter which extends MediaTypeFormatter, and I set a breakpoint on the first line of my implementation of OnReadFromStreamAsync(). However, the breakpoint is never hit because the hangup happens before ever hitting the JSON Deserializer.
I really have no idea where this hanging is occurring from because I receive no exception, just an indefinite hang and occasional Azure emulator crash.
Thank you in advance for any help or insight you might provide!
This sounds like a bug. The good thing is that you can get updated developer bits form codeplex.
There is a chance what your experiencing is related to one of these:
WebAPI: Stream uploading under webhost is not working
DevDiv 388456 -- WebHost should not use Transfer-Encoding chunked when
content length is known.
Zero ContentLength without content type header in body is throwing
If the updated bits don't fix your problem I suggest you try the standard media formatters to rule in/out your formatter. Failing that, then submit an issue.
Say i have an API exposing two related resources, Company which has many Employees.
Say I create a new Company: POST http://domain/api/company/ which returns something like http://domain/api/company/123.
If company/123 is removed from the system (say by a DELETE) then GET http://domain/api/company/123 could return HTTP response code 410 (Gone).
My question is this. If I now try to create an Employee under Company/123 by doing POST http://domain/api/employees/ (with companyId set to 123 in the request body) what HTTP response code should be sent back by the server due to the invalid request?
E.g. the request is correctly formated, but there is a logical error due to the fact that company 123 is gone.
Internal Server Error 500?
Not a 500, because there is no problem with the server.
I would suggest 409 Conflict.
From the RFC:
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
It doesn't exactly match your case, but it is very close IMHO.
For example the server could tell you the parent resource does not exist for you to post to, and you can "resubmit" the employee to a different company. :)
I ran in the same situation here.
After evaluating the HTTP Status code options, it appears to me the best option is to return a 424 Failed Dependency
The 424 (Failed Dependency) status code means that the method could
not be performed on the resource because the requested action
depended on another action and that action failed. For example, if a
command in a PROPPATCH method fails, then, at minimum, the rest of
the commands will also fail with 424 (Failed Dependency).
From RFC
Consider simple case where user is deleting a post. This is simple HTTP DELETE/POST request with one mandatory field, post_id.
What should server do if post_id is not provided?
Apparently, user should never encounter this behaviour, so let's be puristic.
My first take would be 400 bad request, but spec says
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
and I'd say missing field is OK from syntax/http POV, it's application domain-specific semantic requirement.
200 OK with explanations is bad, 500 feels weird as this is request problem.
Thoughs?
400 is the correct response.
400 is not restricted to a malformed syntax from an HTTP point of view. Missing a mandatory argument is an error in the syntax defined by the application and thus a "Bad Request"
EDIT
At first it seems strange that there is no separate return code for this, but the return codes are designed to differentiate in what actions the client should take. A 400 error code means that the client should change the POST data or query string to the format defined by the application. Hence it is appropriate for this case.
In a REST scenario, the resource to be deleted should be identified by the URL, so the ID of the resource should be a part of that URL in order to properly identify it. Once that assumption is correct, then the URL either is identifying a different resource fr deletion, or it isn't (which would give a 404)
In the general case of a missing parameter, however, I often use a 403 Forbidden error. The reasoning is that the request was understood, but I'm not going to do as asked (because things are wrong). The response entity explains what is wrong, so if the response is an HTML page, the error messages are in the page. If it's a JSON or XML response, the error information is in there.
From rfc2616:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.