GraphQL & HTTP responses
Listening to an episode of Syntax the other day, Scott mentioned that in GraphQL land, the received wisdom is to always return a
200 OK HTTP response from your API endpoints, regardless of whether there were any errors running the query; instead, any query errors should be returned in an
errors array in the GraphQL response.
This feels... weird? I've done a bit of GraphQL but I've never worked on an application complicated enough to really warrant it; and in REST-land, an HTTP server connects directly to a database, and query errors are sort of mapped to HTTP response errors (e.g. if a query returns no results, that's returned as a
404 Not Found). On GraphQL servers, however, there's another layer between the HTTP server and the database (the GraphQL bit). The fun thing about GraphQL is that it's sort of transport-layer-agnostic: HTTP might be the most common choice for sending data, but it's not the only one. GraphQL's equally at home being sent over websockets, for instance, or TCP (although I'm not sure what'd go into configuring that one). For that reason, GraphQL doesn't have an opinion on HTTP response codes: it handles errors using the
errors key in its response.
All of which actually does make sense, even if it feels a little icky to me. A common pattern is to return non-200 HTTP status codes for errors that happen outside the GraphQL query context—a
401 Unauthorized, for instance, if a user authentication is performed at the server (rather than GraphQL) layer. While I think that this is a nice compromise, it means that clients have to check two places for a successful response: the
errors object and the HTTP status code. Which again feels icky. But maybe that's just one of the tradeoffs in an application worthy of a GraphQL API.