Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I still like REST. Most web applications are CRUD and don't need RPC. It also provides a standard and expected interface for 3rd party developers integrating with your code. If you're a small saas startup, nobody is going to waste their time learning the particularities of your protocol. Also makes the code very easy to read if you follow best practices for MVC style webapis with dependency injection. In my view, asp.net core is the apex of all RESTful frameworks


Precisely right. Standards work cause everyone understands them. I know a PUT request is almost certainly an update of some kind. I know a POST makes something.

For most shit you wanna do, its view, edit, delete, its really not that complicated.


One team got a stream of 404’s not because the requested objects did not exist in the DB, but because the service moved. Web server was saying: resource does not exist.

Another time, the server had the resource but didn’t like the state of the data, so refused to serve it. Debate ensued as to whether this was a 400 or 500 class error. People got religious.

Yes there’s an answer but it should be so obvious that we don’t have the debate. This isn’t sophisticated verbs, both happened with GET.


TL;DR - API developers should make it so consumers have the necessary information and tools to know what's happening. If you're just returning a 404 with no other info, you have a bad API.

There's basic error handling/reporting that seems to transcend technology and architecture, and a big part of that is that errors should have unique error codes. In the context of a web API, both "route not found" and "resource does not exist" should return a 404, but each should have a unique `code` in the body:

    {"code": 0, "err": "route not found"}
    {"code": 1, "err", "user not found"}
For HTTP, the status code is often for general application development, and the error code is for debugging, though there can be overlap and it's completely fine if a client wants to implement custom logic based on `body.code`.

A validation error should look like:

   {"code": 2, err: "invalid", "data": {
      "username": [{"code": 100, "err": "required"}],
      "password": [{"code": 101, "err": "must be at least 6 characters", "data": {"min": 6}}]
   }}

The `code` always indicates what other data, if any, exists. Above, a code of 2 means there'll be a `data` field of errors. A validation error of `101` means there'll be a `min` field in `data`. `err` is an user-safe (developer friendly) description of the message which can always be regenerated from `code` + `data`.

For errors that aren't known ahead of a time (e.g. a server error), that should also have a distinct code, say 500, and the "data" field should contain an `error_id` which can be used to look up the error.


> In the context of a web API, both "route not found" and "resource does not exist" should return a 404, but each should have a unique `code` in the body

I forget if it was 404 or something else, but you should check if it actually works first. One of our sites did exactly as you suggest here, and it worked totally fine in development (django "runserver"), but didn't work in production (wsgi behind apache). Turned out with that HTTP code, apache was discarding the body.


There’s a standard format for errors in JSON described in RFC 7807:

https://datatracker.ietf.org/doc/html/rfc7807

People shouldn’t invent their own custom error JSON when a standardised format will work.


Absolutely. In fact, you're almost perfectly describing the JsonAPI standard for returning errors: https://jsonapi.org/format/#errors

One improvement I'd steal from theirs and drop in yours - constant (or enum) string codes. It's a lot more scannable when debugging/reviewing/maintaining than having to look up integer codes in a table.


Just pointing out that codes make it easier to provide translations and ability to switch between error types with more confidence than string matching.

Error codes should be accompanied by helpful messages so you don't have to look up the table.


This makes sense if your web API asserts that all responses are JSON responses, and if it provides a schema for responses somewhere as a contract.

But, in general, it's totally fine to return a 404 with no other info. That's a totally acceptable API.


Obviously a bad server state should be 500


Yeah, from what I understand 400 means "fix it at the client's end" and 500 means "fix it at the server's end" which seems to be what the RFC thinks, too:

https://httpwg.org/specs/rfc9110.html#overview.of.status.cod...

> The 4xx (Client Error) class of status code indicates that the client seems to have erred.

> 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.


Basically, 4xx is telling the client you did something wrong (such as visit a non-existent URL), 5xx is when the server errors and can't respond appropriately.


Obvious to you and me. Server team disagreed and tried 422 unprocessable entity, which is not correct. My point is that these issues should be clear enough that there are not thousands of StackOverflow questions on it, and debates between teams. “It’s so easy” is not true. There are layers of understanding.


They are clear, the server team is objectively wrong


Am I the only one around here who hates the whole PUT PATCH nonsense? When I write APIs, you’re either querying data with a GET, or mutating data with a POST. Everything else is a waste of time.


Yea, I also frigging hate it.

Everytime i need to plan out an API i stumble into a lengthy PUT/PATCH analysis and read up session that shouldnt really be necessary.

POST should be the only thing needed, if the object already exists, mutate it, if not, create it, in 99% of the times you dont need the “idempotency” argument.


This suggests you just don't grok HTTP semantics.


No no, this just means I think the HTTP semantics are overkill, and a simple GET/POST gets across everything that I need to.


If your application models a remote API in terms of endpoints which are either read-only/GET or read-write/POST, then you're subverting your own interests. There's no reason to constrain yourself in this way.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: