Search code examples
apolloapollo-server

Get query/mutation operation name


How can I get the operation name in the context? In resolver I can get that with info parameter.

import { ApolloServer } from 'apollo-server'

const server = new ApolloServer({
  context: ({ req }) => {
    // Get query/mutation operation name like getAllUsers
  }
})

server.listen()

Solution

  • Using the technique suggested in my comment, I was able to retrieve the operation name.

    Let's say you have the following query:

    query foo {
      baz {
        id
        name
      }
    }
    

    req.body has two keys that are relevant:

    1. req.body.query holds the entire query in a string format, with whitespaces and carriage returns preserved. While you can retrieve operation names from that string, it will require a bit of string manipulation ; namely, turning the string into an object, and then grabbing the root level key(s) (which can be multiple in case you trigger multiple operations within a single query). With the example above, this key will hold the following string: 'query foo {\n baz {\n id\n name\n }\n}'.

    2. req.body.operationName holds the name you gave your query, IF you named it. With the example above, this key will hold 'foo' (not 'baz' which is the name of the actual operation). You could however decide to exploit this facility by carefully naming your queries according to the operation they contain (this won't work if you trigger multiple ops within one query, however). If you do not name your query, this field holds null.

    Edit: See How to parse GraphQL request string into an object here on SO for a way to turn the string retrieved in method 1 into a JS object and retrieve your actual operation name.

    Further considerations:

    Method 2 would really be appropriate for debugging purposes, for instance. Say you want to log variables for a specific query, you could name it and do the following:

    const server = new ApolloServer({
      context: ({ req }) => {
        if (req.body.operationName === 'debugMe') {
          console.log(req.body.variables)
        }
      }
    })
    

    However, because Method 2 relies on the client naming the query, it cannot be used reliably for business logic purposes. Only Method 1 will correctly retrieve the operation name regardless of how the query is formed on the client side.