• Hanzito (unregistered)

    at least you ... aren't sending the client a malformed document

    Can do that, though. I inherited such a project. It parses an Excel file, stores it in a most abhorrent way, and when the client asks for the list of available documents, it doesn't just return the file names, but formats the documents first, which goes bad on date fields, which results in an exception, which mangles the JSON reply. From that point on, the client becomes unresponsive, and you have to delete a record from the database to get it going again.

    I'm glad for you, you didn't have to suffer something similar.

  • dusoft (unregistered)

    Give PHP a break.

    You can write shitty code in any language as the Daily WTF demonstrates every day.

  • Argle (unregistered) in reply to dusoft

    You can write shitty code in any language as the Daily WTF demonstrates every day. Yes, but PHP invites you to and helps in every way possible.

  • (nodebb)

    I'm always going to feel weird about using a success field when ideally the HTTP status code could convey most of that information (and yes, I know there are reasons to still put status in the body, I just hate it).

    Surely you don't mean you would put application-context status into the field meant for request-response-context status.

  • Álvaro González (github)

    In my former employer, certain clients used either PHP or Java. The only way to tell for sure was to look at file extensions, or see if variable names started with dollar sign, because the code patterns were as identical as two pieces of code written in different languages can be.

  • (author) in reply to dpm

    If the HTTP header is good enough for the verb describing our operation, I think it's good enough for the result code of that verb, yes.

  • (nodebb) in reply to Remy Porter

    If I worked with you, I wouldn't work with you. The HTTP header is for information about the HTTP transport transaction --- status of the actual application transaction belongs in the body, because they are two separate operations.

  • (author) in reply to dpm

    It depends on our service. Are we trying to be RESTful? Then we should be putting as much into the HTTP layer, because that's kinda the agreement of REST. The HTTP status code is the operation, because the operation is definitionally an HTTP request. If I do a POST to update a record, and that fails, then the HTTP request failed and that should be conveyed in the HTTP status.

    Are we, on the other hand, going more RPC? Then yes, HTTP is just a transport, and the operation and the request are two different things. But then the WTF is using HTTP for RPC, which is a terrible fit. Yes, I'm looking at you, SOAP. An extremely common bad fit, like polyester leisure suits in the 70s.

  • A Human (unregistered) in reply to dpm

    That is either one of the dumbest things I've ever heard, or I myself am stupid.

    What's the difference between the http transaction and the application transaction? The application is a http server, right? Would you return 200 OK and { error: "Too many requests" } from an api because it understood the request and could fulfil it but couldn't be f*cked?

  • MaxiTB (unregistered) in reply to Hanzito

    You lost me at Excel file :-)

  • Your Name (unregistered)

    @A Human: I'm with dpm there. REST does the most stupid thing by mixing transport protocol and content. Yes, 200 OK with "error too many requests". You reached the server technically ok. The inner actual API has a problem.

    How would you differ between too many requests on the web server and too many requests on the API itself on the client?

    I absolute hate it when REST APIs return 404, because an item is not found in the database. So, did you call the correct URL? Or just got the wrong ID of an item?

    Proper developers stayed as far away from web dev and it shows.

  • MaxiTB (unregistered) in reply to dpm

    status of the actual application transaction belongs in the body

    You can sadly put into your HTTP bidy whatever you want since detailed error messaging is not standardized, however if you server cannot handle the request, you have to respond with a 5xx error code and it doesnt matter which layer is failing on the server.

  • 516052 (unregistered) in reply to A Human

    Task failed successfully.

  • Mpripper (unregistered) in reply to A Human

    There might be valid use cases with async processing like

    POST /longHeavyProcess (params in request-body) => {"Id": 123}

    GET /longHeavyProcess/123/status => running/success/failed

    GET /longHeavyProcess/123/result => Hello World!

    The status response itself would be a 200 because it returned the status, even if the process failed. The result request would however fail with some 4xx code (maybe 424 Failed dependency?)

  • 516052 (unregistered)

    As per RFC 9110:

    The 5xx (Server Error) class of status code indicates that the server is aware that it has erred or is incapable of performing the requested method. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. A user agent SHOULD display any included representation to the user. These status codes are applicable to any request method.

    I would say that this is quite definitive. If the server fails to complete the operation for any reason it should send 500 and an explanation.

  • 516052 (unregistered)

    Note that SHOULD is not the same as MUST here.

    SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

    So you are allowed to not do it if you really want to. But its strongly suggested you don't.

  • (nodebb) in reply to A Human

    What's the difference between the http transaction and the application transaction?

    Not every web page is a REST API.

    If you have a form and the user entered an invalid value in a field, the HTTP request was handled fine, but there was an error at the application level. If you send an HTTP status indicating an error, the user's web browser may not display the friendly error page that keeps all of the form fields filled in and points the user to the field where the error is.

  • 516052 (unregistered) in reply to Dragnslcr

    If you are sending the entire form over the internet and back just for basic validation you are doing it wrong. Basic validation should always be done on the frontend so that all data which enters your processing system is always valid (even if potentially incorrect).

    Doing anything else risks allowing security errors and server exceptions. Neither of which are good.

  • (nodebb)

    I've read all the replies and I'm still standing where I was: if the backend catches an exception during a SQL operation, I'm returning 200 in the status code to reflect that everything at the transport level worked correctly, and the frontend knows where to look for the application success/failure/message fields within the body.

    I realize this is subjective, so we're not going to agree. To me, there is a difference between handling a failure of any kind at the HTTP level vs. handling a failure within the application.

  • (author) in reply to dpm

    Here's my counterpoint to that. Why should I leak anything about my internal implementation to clients? If there was a database error, I don't want them to even know there's a database. It's none of their business. I want to send back a generic, "Nope, not gonna happen" error code. And that's true even if my team is responsible for the client. No information but domain information crosses module boundaries! Diagnostics can get logged, or broadcasted out to an entity that can deal with them- the database error could likely raise an alert in my monitoring system, but I see no reason why I should give the client that information.

  • 516052 (unregistered) in reply to dpm

    There absolutely is a difference between the two. I completely agree. But if you are going to actually follow the HTTP standard as written it defines how to cover both.

    Codes in the 200 range are for when the entire stack, communications and application both succeed, codes in the 400 range are for when the communications stack fails and codes in the 500 range are for when the communications stack succeeds but the application fails.

  • 516052 (unregistered)

    I can't edit so I'll just add.

    And there are good reasons why you want to follow the standard. Those different codes are the accepted, well known and easily recognized way that everyone is used to handling things. By deviating from it you are essentially creating an API that is going to make things needlessly difficult for any and all users.

  • (nodebb) in reply to Remy Porter

    [...] I don't want them to even know there's a database.

    I can respect, and even agree, with that. You'll notice that I didn't say I would include that information, merely that it would be "handled differently".

  • (nodebb) in reply to 516052

    codes in the 500 range are for when the communications stack succeeds but the application fails.

    Ah, thank you for that, now I realize how I should have been stating my case. You and Remy and the others are technically correct ("The best kind of correct!") but I dislike 5xx codes being sent back by the application without any explicit intent on my part. I don't want to have to worry about overloaded values, so I handle it the way I've described.

  • wondering-in-va (unregistered) in reply to dpm

    I dislike 5xx codes being sent back by the application without any explicit intent on my part

    You get to decide what to status code to return and what message to include with the status codes. Or are you using some framework that doesn't let you build the response?

  • Gumpy Gus (unregistered)

    Roughly similarly, long ago I worked on a very slow Pascal networked database. Heavily overgrown. The framework already had named objects but they wrote their own layer of junk on top. And when they expanded internationally it ran really slow as every transaction was silently doing about seven slow round trips to just order a toothbrush. Should have junked the whole shebang, it was so creaky.

  • 516052 (unregistered) in reply to wondering-in-va

    That is what I am curious about as well. I have not ever seen a system where I did not have full control over what happens to the response.

  • (nodebb) in reply to 516052

    It's easy:

    4xx errors: Client did something wrong, with 400 for when nothing more specific is in the standard codes.
    5xx errors: Server did something wrong, with 500 for when nothing more specific is in the standard codes.

    If input validation fails, throw a 400 back in their face because they composed their request wrong. Database connection just went wonky for some reason? That's a 500 because it's not the client's fault. Got some blecherous mess of a microservice stack? Well, individually they might be giving a 400 for something, but the orchestrator may still turn that into a 500 if it can't mitigate.

Leave a comment on “The JSON Template”

Log In or post as a guest

Replying to comment #696494:

« Return to Article