According to the spec:
By default, all types in GraphQL are nullable; the null value is a valid response for all of the above types. To declare a type that disallows null, the GraphQL Non‐Null type can be used.
In other words, types in GraphQL are nullable by default. So a field like
getUser: User
may return either a User object or null. A field like
name: String
may return either a String or null. Only by explicitly specifying a field as non-null (in SDL, by appending a ! to the type), can we specify that a field should never return null. For example:
name: String!
It's also important to note that the Promise returned in your resolver must resolve to either null or undefined in order to be coerced into a null value. In other words, if you return an empty object ({}), an empty array ([]) or some other value, GraphQL will treat this as you returning an object and not a null value!
In your schema, the email field on User is String!, meaning it cannot resolve to null. If you run a query like
query {
getUser(user_id: "1") {
email
}
}
and the resolver for getUser returns an empty object ({}), GraphQL will attempt to resolve email, return null for it and blow up because email is not supposed to be null! If, however, getUser resolves to null, none of the child fields will be resolved and you will not get any error.