Есть ли способ преобразовать строку запроса graphql в объект GraphQLResolveInfo?

#node.js #graphql

#node.js #graphql

Вопрос:

Я написал программное обеспечение, которое анализирует и форматирует четвертый параметр функции распознавания graphql (объект info) для использования в другом месте. Я хотел бы написать модульные тесты для этого программного обеспечения. В частности, я не хочу создавать GraphQLResolveInfo объект самостоятельно, потому что это было бы очень громоздким, подверженным ошибкам и сложным в обслуживании. Вместо этого я хочу написать понятные для человека строки запроса и преобразовать их в GraphQLResolveInfo объекты, чтобы я мог передавать их в свое программное обеспечение.

После тщательного поиска в Google и чтения graphql-js исходного кода я не нашел простого способа сделать то, что они делают внутри. Я действительно надеюсь, что я чего-то не хватает.

Чего я не пытаюсь сделать, так это использовать graphql-tag библиотеку, потому что это просто генерирует AST, формат которого сильно отличается от GraphQLResolveInfo типа.

Кто-нибудь делал это раньше? Помощь была бы очень признательна!

Ответ №1:

Я буду продолжать следить за этим вопросом, чтобы узнать, появится ли лучший ответ, но мне, наконец, удалось решить мою конкретную проблему, создав максимально близкое приближение GraphQLResolveInfo объекта, которое мне нужно для моего конкретного варианта использования.

GraphQLResolveInfo Объект состоит из нескольких атрибутов, два из которых называются fieldNodes и fragments . На самом деле оба являются частями одного и того же AST, который graphql-tag генерируется из строки запроса. Это единственные части GraphQLResolveInfo объекта, которые касаются программного обеспечения, которое я написал, остальное игнорируется.

Итак, вот что я сделал:

 import gql from 'graphql-tag';

// The converter function
const convertQueryToResolveInfo = (query) => {
    const operation = query.definitions
        .find(({ kind }) => kind === 'OperationDefinition');
    const fragments = query.definitions
        .filter(({ kind }) => kind === 'FragmentDefinition')
        .reduce((result, current) => ({
            ...result,
            [current.name.value]: current,
        }), {});

    return {
        fieldNodes: operation.selectionSet.selections,
        fragments,
    };
};

// An example call
const query = gql`
    query {
        foo {
            bar
        }
    }
`;
const info = convertQueryToResolveInfo(query);
 

Из AST, сгенерированного graphql-tag , я извлекаю и изменяю определения операций и фрагментов, чтобы они выглядели так, как они выглядят внутри GraphQLResolveInfo объекта. Это ни в коем случае не идеально и может быть изменено в будущем в зависимости от того, как развивается мое программное обеспечение, но это относительно краткое решение для моей конкретной проблемы.