GraphQL Node.js: определить, какие типы используются в запросе - PullRequest
0 голосов
/ 02 ноября 2018

Учитывая, что у меня есть схема, которая имеет типы: пользователь, комментарий, сообщение, изображение; Можно ли определить типы GraphQL, используемые в запросе, с учетом запроса и схемы? например если у клиента был запрос

{
    user(userName: "username") {
        email
        comments
    }
}

В этом случае запрос имеет типы Пользователь и Комментарий. Можно ли определить программно, используя пакеты graphql-js или graphql для node.js?

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

При наличии допустимой строки документа, представляющей некоторую операцию GraphQL, вы можете проанализировать строку в AST.

import { parse, validate } from 'graphql' 

const document = parse(someDocumentString)
// if you want to validate your document to verify it matches your schema
const errors = validate(schema, document)

AFAIK, нет утилиты для получения массива типов в документе, если это то, что вы просите, но вы можете просто пройти AST и собрать любую информацию из него. В качестве примера, вот как GraphiQL делает это для генерации карты переменных с соответствующими им типами:

import { typeFromAST } from 'graphql'

export function collectVariables(schema, documentAST) {
  const variableToType = Object.create(null);
  documentAST.definitions.forEach(definition => {
    if (definition.kind === 'OperationDefinition') {
      const variableDefinitions = definition.variableDefinitions;
      if (variableDefinitions) {
        variableDefinitions.forEach(({ variable, type }) => {
          const inputType = typeFromAST(schema, type);
          if (inputType) {
            variableToType[variable.name.value] = inputType;
          }
        });
      }
    }
  });
  return variableToType;
}
0 голосов
/ 06 ноября 2018

Для всех, кто сталкивается с этим, я нашел ответ в посещении и TypeInfo Вот функция, которая берет запрос GraphQL (документ) и схему и возвращает, какие типы данных из схемы используются.

import { visit } from 'graphql/language/visitor'
import { parse } from 'graphql/language'
import { TypeInfo, visitWithTypeInfo } from 'graphql'
import { schema as _schema } from '../src/schema/schema'

const getQueryTypes = (schema, query) => {
    const typeInfo = new TypeInfo(schema)
    var typesMap = {}
    var visitor = {
        enter(node) {
            typeInfo.enter(node)
            typesMap[typeInfo.getType()] = true
        },
        leave(node) {
            typesMap[typeInfo.getType()] = true
            typeInfo.leave(node)
        }
    }
    visit(parse(query), visitWithTypeInfo(typeInfo, visitor))
    return Object.keys(typesMap)
}

const _query = `
    query {
        ...
    } 
`

console.log(getQueryTypes(_schema, _query))
0 голосов
/ 02 ноября 2018

Вы должны создать типы, используя GraphQLObjectType, например:

export default new GraphQLObjectType(
  ({
    name: 'User',
    description: 'Represents a User',
    fields: () => ({
      _id: {
        type: GraphQLNonNull(GraphQLString),
        resolve: user => user._id,
      },
      name: {
        type: GraphQLNonNull(GraphQLString),
        description: 'Name of the user',
        resolve: user => user.name,
      },
      createdAt: {
        type: GraphQLString,
        description: '',
        resolve: user => user.createdAt.toISOString(),
      },
      updatedAt: {
        type: GraphQLString,
        description: '',
        resolve: user => user.updatedAt.toISOString(),
      },
    }),
  }: GraphQLObjectTypeConfig<User, GraphQLContext>),
);

Затем вы можете использовать это UserType для другого типа, объявив, например, type: GraphQLNonNull(UserType).

https://graphql.org/graphql-js/constructing-types/

Надеюсь, это поможет:)

...