none
WebApi - HTTP Response status 200 vs 400 RRS feed

  • Question

  • Hi,

    I have an api (webapi) in rest style.

    In the login Controller when the authentication fails it is return http status 401(unauthorized) and a json structure indicating the remaing allowed retries et all.

    When the request has some invalid data (ex: invalid range, invalid amount) the APIresponds with http status 400 (bad request) and a generic json structure indicating the errorCode, errorDesc, CorrelationId et all

    Now, I have a client using my API telling me I should not return http status 400. He says I shoul allways return http status 200 because the success or failure is allready indicated inside the json strucuture returned.

    I'm not doing things correctly by returning http status 400 (bad request) when the request contains invalid data?

    Is there any architectural style against this?

    Please advise, and if you have examples os public apis returning http status 400, I will appreciate that

    Thank you so much ,

    PG

    • Moved by CoolDadTx Monday, September 25, 2017 2:05 PM ASP.NET related
    Sunday, September 24, 2017 1:09 PM

All replies

  • I disagree with your client completely. While I have seen it done both ways, it scatters handler logic all over the place and is not maintainable. Imagine I don't check for a 404 but instead look for a response code in the return, what happens when I query the wrong url? Now I need to have 404 handling in two places (depending on the client). In your case, I don't think it is any different. The request is invalid and not worthy of a valid response. By conceding to his suggestion, both yours and his code become unmaintainable to other developers who now have to accommodate this practice and make one off calls as to how to handle a case and somehow convey that to every consumer suggesting instead when you expect an error, you may or may not get one?
    Sunday, September 24, 2017 3:12 PM
  • HTTP codes are meant for the HTTP layer of your application so you shouldn't be using them.  Business rules are completely different, which is what you are describing,  and are application specific, so you need to come up with your own protocol.

    What should have been returned is  "200 OK" with a body describing what happened with the request. The specification clearly describe it.

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1

    <copied>

    OK 200

    The request has succeeded. The information returned with the response  is dependent on the method used in the request, for example:

    <end>

    Did the  HTTP request succeeded? Yes it did, and the web server knew what to do with that request and passed it on to a Web service method.

    "400 Bad Request" means, that the web server did not understand what was wanted. It means that the request didn't even reach the service method, and the application never received the request.

    Sunday, September 24, 2017 4:00 PM
  • REST was conceived long after the HTTP specification and they are not the same. Consider the following:

    User sends a GET to an endpoint's resource http://host/api/service/things that exposes a collection, if no objects are available, a 2xx is returned and the data is an empty collection. If objects do exist, a 2xx response with a body containing the collection is returned.

    If the user then attempts to query the details for one of those objects, http://host/api/service/things/42 and the object was found, the response would be 2xx plus a body containing the details. If not, common practice is 404 and you can optionally include a body with rich response content. Look through example in the Microsoft documentation, such as https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api,https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results and https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/controller-methods-views.

    I don't believe you can translate the semantics for the original web content related HTTP specification to REST without some re-interpretation. The request is bad in this context and while its fine to pleasantly return a rich response, that doesn't change the fact in my opinion.

    Every API I can think of at the moment behaves this way, for example see the Oxford Dictionary, https://developer.oxforddictionaries.com/documentation/response-codes, you'll get a 404 if you ask for a word that does not exist in their dictionary.

     
    Sunday, September 24, 2017 6:12 PM
  • HTTP codes are meant for the HTTP layer of your application so you shouldn't be using them.  Business rules are completely different, which is what you are describing,  and are application specific, so you need to come up with your own protocol.

    What should have been returned is  "200 OK" with a body describing what happened with the request. The specification clearly describe it.

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1

    <copied>

    OK 200

    The request has succeeded. The information returned with the response  is dependent on the method used in the request, for example:

    <end>

    Did the  HTTP request succeeded? Yes it did, and the web server knew what to do with that request and passed it on to a Web service method.

    "400 Bad Request" means, that the web server did not understand what was wanted. It means that the request didn't even reach the service method, and the application never received the request.

    I understand that. It makes some sense (although it has the overhead of inspecting the response body and not only the htt response status code).

    Also worth mentioning is the fact that big players (twitter api, dropbox api, google cloud api, oracle cloud api) with public apis use http status 400 when the request contains invalid/erroneous data)

    So, if my api receives a request to execute one operation with an invalid decimal amount or an invalid destination "bank account", Isn´t correct for me to return the status code 400?

    It seems to me it can be a bit of a philosophical or subjective thing, but I really like to discuss with others. It might help me to prepare for some discussions ahead at work.

    Thanks,

    PG

     
    Sunday, September 24, 2017 6:26 PM
  • you can post to webapi forum in asp.net forums

    http://forums.asp.net/

    Sunday, September 24, 2017 8:31 PM
  • I agree that not everything should come back as a 200. Keeping with that, not every little thing like a invalid destination for a bank account should constitute a bad request as when an application is written properly there would be validation on the front end site that works in tangent with bad end code where working together the front end code might have a validator which when validation happens either for a form or single element it can handle the issue without having the backend get involved. 

    Now the following is an example of throwing and bad request. For whatever reason the repo (repository) failed to update an entity received from the font end where in this case the controller signature is shown below this code and there may had been an issue at either that level or in the ContactRepository that could not be handled thus a BadRequest is thrown and the javascript ajax callback is setup to handle it gracefully (in our case at least which logs it and if needed pushes a Kendo notification message to the user).

    [HttpPut]
    public override async Task<IHttpActionResult> Put(int id, ContactDTO pObject)
    {
    
        Contact contact = Mapper.Map<ContactDTO, Contact>(pObject);
        bool success = await Repository.Update(contact);
    
        if (success)
        {
            return Ok("Updated successfully");
        }
        else
        {
            return BadRequest("Failed to update");
        }
    }

    .

    public class ContactsController : BaseSingleItemRevenueAPIController<Contact, ContactDTO, ContactRepository>
     

    The above is one case taken from one of our applications where in most cases when an exception of any nature is thrown whomever is working on the frontend works with the backend developer to ensure everything is handled gracefully with a fallback to a global method to handle exceptions including authentication via Azure B2C.

    You should be writing test, both success and failures to ensure everything is in order.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Monday, September 25, 2017 12:39 AM
  • Also worth mentioning is the fact that big players (twitter api, dropbox api, google cloud api, oracle cloud api) with public apis use http status 400 when the request contains invalid/erroneous data)

    I guess that's why you see more and more of these sites being compromised. You know like 200 OK nothing to see here, but an error description is coming back under the hood if error. On the other hand, a 400 error code is coming back with check amount bad, account number is invalid, etc. ect.

    Oh wait, let me, the black hat, see what other errors with HTTP status codes with possible descriptive error message that the service is going to toss back to see if it can be compromised on some exploit.

    Monday, September 25, 2017 2:17 AM
  • Please post questions related to ASP.NET in the ASP.NET forums.
    Monday, September 25, 2017 2:04 PM