What is an exclamation point in GraphQL?

What is an exclamation point in GraphQL?

127

In a schema file that I have I noticed there are exclamation marks after some types, like

# Information on an account relationship
type AccountEdge {
  cursor: String!
  node: Account!
}

What do these mean? I can’t find anything about it in the documentation or through googling ?

Share
Improve this question

3 Answers
3

Reset to default

139

That means that the field is non-nullable.

See more info in Graphql – Schemas and Types

Share
Improve this answer

4

  • 3

    This took longer to find out than I expected. Even the GraphQL cheatsheets and the Prisma and Apollo docs didn’t seem to mention that explicitly.

    – Jacob

    Nov 30, 2018 at 0:25

  • Documentation link with nifty highlighting (works in Chrome): graphql.org/learn/schema/….

    – Purplejacket

    Jan 27, 2021 at 22:06

  • @Purplejacket That’s fancy, I updated the link in the answer! 🙂

    – Juan

    Jan 28, 2021 at 16:55

  • makes sense right? if ? often means nullable, then ! would mean non-nullable

    – netotz

    Apr 7, 2022 at 17:49

52

From 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. This type wraps an underlying type, and this type acts identically to that wrapped type, with the exception that null is not a valid response for the wrapping type. A trailing exclamation mark is used to denote a field that uses a NonтАРNull type like this: name: String!.

In other words, types in GraphQL are nullable by default. An exclamation point after a type specifically designates that type as non-nullable.

This has different implications depending on where the type is used.

Output

When non-null is applied to the type of a field, it means that if the server resolves that field to null, the response will fail validation. You may still receive a partial response, as long as the error does not propagate all the way up to the root.

For example, given a schema like:

type Query {
  user: User
}

type User {
  id: ID!
}

Here the id field is non-null. By marking the field as non-null, we are effectively guaranteeing we will never return null for this field. If the server does return null, then it’s an indication that something went terribly wrong and we want to throw a validation error.

Input

When non-null is applied to the type of an input, like an argument, input object field or a variable, it makes that input required. For example:

type Query {
  getUser(id: ID!, status: Status): User
}

Here, the id argument is non-null. If we request the getUser field, we will always have to provide the id argument for it. On the other hand, because the status argument is nullable, it’s optional and can be omitted. This applies to variables as well:

query MyQuery ($foo: ID!) {
  getUser(id: $foo)
}

Because the $foo variable is non-null, when you send the query, it cannot be omitted and it’s value cannot equal null.

A special note on variable types

Because the id field is a non-null ID (i.e. ID!) type in our example, any variable we pass it must also be a non-null ID. If our $foo variable was a nullable ID, we could not pass it to the id argument. The opposite, however, is not true. If an argument is nullable, you can pass it a non-null variable.

In other words:

+----------+----------+--------+
| Argument | Variable | Valid? |
+----------+----------+--------+
| String   | String   |   тЬЕ   |
| String   | String!  |   тЬЕ   |
| String!  | String   |   тЭМ   |
| String!  | String!  |   тЬЕ   |
+----------+----------+--------+

Share
Improve this answer

0

1

TLDR: it means throw an error if value is null

User tried to send null for an input field which has ! -> instant error response

Server tried to return null for a field that has ! -> return an error instead

Why would you add ! if it only throws errors ?

If you know that a null in the input would crash your server then better to throw the error early.

If you know that a null in the response would crash your client then better to throw the error early.

I’m using “crash” broadly to refer to all possible bugs or volnurabilities that could occur.

Example

Schema:

type Query
{
    data(input: InputType!): ResponseType!
}

input InputType
{
    inputField: String!
}

type ResponseType
{
    field: String!
}

Input Variables which are OK:

{
    input: {
        inputField: "sample text"
    }
}

Input Variables which will throw errors:

// error: inputField is null
{
    input: {
        inputField: null
    }
}

// error: inputField is null (because it's missing)
{
    input: {
    }
}

// error: input is null
{
    input:  null 
}

// error: input is null (because it's missing)
{
}

Server Response which is OK:

{
    data: {
        field: "sample text"
    }
}

Server Responses which will throw errors:

// error: field is null
{
    data: {
        field: null
    }
}

// error: field is null (because it's missing)
{
    data: {
    }
}

// error: data is null
{
    data: null
}

Share
Improve this answer



Your Answer


Post as a guest

Required, but never shown


By clicking тАЬPost Your AnswerтАЭ, you agree to our terms of service, privacy policy and cookie policy

Not the answer you’re looking for? Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *