Skip to content

Clarification about usage of 404 not found in the application/graphql-response+json spec #446

Open

Description

@OhMyGuus

Hey hey,

Not sure if this is the right place to ask, but hopefully someone can still help us out :)

We are currently implementing application/graphql-response+json, which means we should use standard HTTP status codes. We are, however, having a discussion about how to handle cases where the requested data, such as a user, does not exist.

According to this specification, should we return a 404 status code, or should we return a 200 response with "data": null?
We could not find this scenario in the section with all the 4xx status code examples, which made us wonder. ​‌

Thanks in advance 😄

Activity

  1. martinbonnin commented on Oct 15, 2026

    @martinbonnin
    Contributor

    Hi 👋

    I'd recommend using partial data and 294 200 (edit: no error so no need for 294) for these use cases:

    query GetUserAndProducts($userId: ID!) {
      user(id: $id) {
        id 
        name
        email
      }
      products {
        name
        price
      }
    }

    Some of the user data may not exist in your graph but other data might still be present:

    {
      "data": {
        "user": null,
        "products": [ 
           // actual data here ... 
         ]
      }
    }
  2. OhMyGuus commented on Oct 15, 2026

    @OhMyGuus
    Author
    1. Hi 👋
      I'd recommend using partial data and 294 for these use cases:
      query GetUserAndProducts($userId: ID!) {
      user(id: $id) {
      id
      name
      email
      }
      products {
      name
      price
      }
      }

      Some of the user data may not exist in your graph but other data might still be present:
      {
      "data": {
      "user": null,
      "products": [
      // actual data here ...
      ]
      }
      }

    Thanks already 😄, just to double-check:

    If the query and response were as follows:

    query GetUser($userId: ID!) {
      user(id: $id) {
        id
        name
        email
      }
    }
    
    {
      "data": {
        "user": null
      }
    }
    

    Would you still return 294 in that case, or would u use 404 or a 200 in this case there is no data now at all but the graph succeeded... 😅

  3. martinbonnin commented on Oct 15, 2026

    @martinbonnin
    Contributor
    {
      "data": {
        "user": null
      }
    }

    This is actually a case of 200, not 294 because there is technically no error, it's just a field that returns null, I have updated my response above.

    This is explained here in the spec:

    If the [GraphQL result](https://http-spec.graphql.org/draft/#graphql-result) contains the data entry 
    and it is not null, then the server MUST reply with a 2xx status code.
    
    If the [GraphQL result](https://http-spec.graphql.org/draft/#graphql-result) contains the data entry 
    and does not contain the errors entry, then the server SHOULD reply with a 200 status code.
    

    So you MUST use 2xx and 200 is preferred.

    The 294 could be useful if you have errors as well as data:

    {
      "data": {
        "user": null,
        "products": [ 
           // actual data here ... 
         ]
      }
      "errors": { 
        "path": ["user"],
        "message": "Cannot resolve user"
      }
    }

    Whether you model absence of a user as a null or an error is a schema design consideration. I like using null in that case but the spec doesn't mandate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions