title: Enumerating all fields from a GraphQL query
body: <p>Given a GraphQL schema and resolvers for <a href="https://www.apollographql.com/docs/apollo-server/" rel="nofollow noreferrer">Apollo Server</a>, and a GraphQL query, is there a way to create a collection of all requested fields (in an Object or a Map) in the resolver function?</p>
  
  <p>For a simple query, it's easy to recreate this collection from the <code>info</code> argument of the resolver.</p>
  
  <p>Given a schema:</p>
  
  <pre><code>type User {
    id: Int!
    username: String!
    roles: [Role!]!
  }
  
  type Role {
    id: Int!
    name: String!
    description: String
  }
  
  schema {
    query: Query
  }
  
  type Query {
    getUser(id: Int!): User!
  }
  </code></pre>
  
  <p>and a resolver:</p>
  
  <pre><code>Query: {
    getUser: (root, args, context, info) =&gt; {
      console.log(infoParser(info))
  
      return db.Users.findOne({ id: args.id })
    }
  }
  </code></pre>
  
  <p>with a simple recursive <code>infoParser</code> function like this:</p>
  
  <pre><code>function infoParser (info) {
    const fields = {}
  
    info.fieldNodes.forEach(node =&gt; {
      parseSelectionSet(node.selectionSet.selections, fields)
    })
  
    return fields
  }
  
  function parseSelectionSet (selections, fields) {
    selections.forEach(selection =&gt; {
      const name = selection.name.value
  
      fields[name] = selection.selectionSet
        ? parseSelectionSet(selection.selectionSet.selections, {})
        : true
    })
  
    return fields
  }
  </code></pre>
  
  <p>The following query results in this log:</p>
  
  <pre><code>{
    getUser(id: 1) {
      id
      username
      roles {
        name
      }
    }
  }
  
  =&gt; { id: true, username: true, roles: { name: true } }
  </code></pre>
  
  <p>Things get pretty ugly pretty soon, for example when you use fragments in the query:</p>
  
  <pre><code>fragment UserInfo on User {
    id
    username
    roles {
      name
    }
  }
  
  {
    getUser(id: 1) {
      ...UserInfo
      username
      roles {
        description
      }
    }
  }
  </code></pre>
  
  <p>GraphQL engine correctly ignores duplicates, (deeply) merges etc. queried fields on execution, but it is not reflected in the <code>info</code> argument. When you add <a href="https://github.com/apollographql/graphql-guide/blob/master/source/queries.md#fragments-for-unions" rel="nofollow noreferrer">unions</a> and <a href="https://github.com/apollographql/graphql-guide/blob/master/source/queries.md#inline-fragments" rel="nofollow noreferrer">inline fragments</a> it just gets hairier.</p>
  
  <p>Is there a way to construct a collection of all fields requested in a query, taking in account advanced querying capabilities of GraphQL?</p>
  
  <p>Info about the <code>info</code> argument can be found <a href="https://www.apollographql.com/docs/graphql-tools/resolvers.html" rel="nofollow noreferrer">on the Apollo docs site</a> and in the <a href="https://github.com/graphql/graphql-js/blob/c82ff68f52722c20f10da69c9e50a030a1f218ae/src/type/definition.js#L489-L500" rel="nofollow noreferrer">graphql-js Github repo</a>.</p>