Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL: Returning null vs Throwing Error

Tags:

graphql

In case of errors, I always wonder whether I should return null or throw an error.

Let's say I have a type Person:

type Person {
    firstName: String!
    lastName: String!
}

I want to let the client search for a specific user. This could be done in 2 ways:

Using a nullable type and possibly returning null when no user is found:

type Query {
    getPerson(firstName: String!): Person
}

Using a non-nullable type and throwing an error when no user is found:

type Query {
    getPerson(firstName: String!): Person!
}

Is there a right way to do this?

like image 473
Eyal C Avatar asked Mar 21 '18 21:03

Eyal C


People also ask

Does GraphQL return null?

The server's field resolver returned an explicit null. The field resolver throws. In this case GraphQL will return null for that field. This is true even if the server resolver's return type is non-nullable.

Does GraphQL return null or undefined?

In JavaScript functions without an explicit return statement implicitly return undefined . So our function creates a Promise and then immediately returns undefined , causing GraphQL to return null for the field.

How does GraphQL return error from a request?

If the response includes GraphQL errors, they are returned on error. graphQLErrors and the response data is set to undefined even if the server returns data in its response. This means network errors and GraphQL errors result in a similar response shape. This is the default error policy.

How do you handle null values in GraphQL?

Nulls in the query A GraphQL query can have fields and inputs, with or without variables. Fields are always optional, whether nullable or not. In inputs, such as field arguments, nullable types are always optional and non‐null types are always required.


1 Answers

Interesting question!

First I want to argue that the "errors" part of the response is realy only for developer errors (that means errors that are cause by a developer, either on the backend or on the frontend). For error happening when the API is misused, e.g. wrong arguments are supplied (HTTP 400-403), or something went wrong internally (HTTP 500). In this case something is broken and there is no action required by the user but by the developer. The not found (HTTP 404) is very special since it is often caused by the user of your APP (e.g. you try to access a profile page that does not exist). In this case we want to give feedback directly to the user. "This profile does not exist Go back to homepage" Most client tools don't handle the GraphQL errors very well. This is why errors that should be shown to the user should be part of your response schema. This awesome blog post goes into more detail on the topic.

Now I don't think that you need to return a dedicated GetPersonPayload type in your API but it is certainly a possibility:

type GetPersonPayload {
  person: Person
  errors: [PayloadError!]!
}

type Query {
   getPerson(firstName: String!): GetPersonPayload
}

To summarize: I would definitely return a nullable person and - depending on how futureproof/enterprise your schema should be - you might even want to return a special payload type as described in the linked article.

like image 88
Herku Avatar answered Oct 22 '22 02:10

Herku