17

I have an operation getFoo that requires that the user is authenticated in order to access the resource.

User authenticates using a mutation authenticate, e.g.

mutation {
  authenticate (email: "foo", password: "bar") {
    id
  }
}

When user is authenticated, two things happen:

  1. The request context is enriched with the authentication details
  2. A cookie is created

However, I would like to combine authentication and getFoo method invocation into a single request, e.g.

mutation {
  authenticate (email: "foo", password: "bar") {
    id
  }
}
query  {
  getFoo {
    id
  }
}

The latter produces a syntax error.

Is there a way to combine a mutation with a query?

Gajus
  • 69,002
  • 70
  • 275
  • 438

2 Answers2

16

There's no way to send a mutation and a query in one request according to the GraphQL specification.

However, you can add any fields to the mutation payload. So if there are only a handful of queries that you need to support for the authenticate mutation, you could to this, for example:

mutation {
  authenticate (email: "foo", password: "bar") {
    id
    getFoo {
      id
    }
  }
}

At the end of the day, it might be better to keep the mutation and query separate though. It gets hairy very quickly if you want to include many queries in many mutations like this. I don't see a problem with the overhead of an additional request here.

marktani
  • 7,578
  • 6
  • 37
  • 60
1

This is not possible without support by the server. However:

  • Some GraphQL APIs support batching of operations where you can send an array of queries and/or mutations in a single request.

  • Other APIs support HTTP2+, where you can easily send multiple requests on the same connection without any overhead.

  • If you control the API, you can also apply a little trick where you simply expose the getFoo field not just on the Query type but also on the Mutation type. There is not that much of a difference, except that mutation { … } fields are resolved sequentially. You can go even further and expose the whole Query type on mutations, allowing you to query arbitrary data and not just start querying the graph at the mutation result. It would look like this:

    type Mutation {
      query: Query!
      … # authenticate() etc
    }
    
    mutation authAndFoo {
      authenticate (email: "foo", password: "bar") {
        id
      }
      query {
        getFoo {
          id
        }
      }
    }
    
Bergi
  • 630,263
  • 148
  • 957
  • 1,375