有没有一种方法可以将graphql查询字符串转换为GraphQLResolveInfo对象?

时间:2019-04-17 17:47:49

标签: node.js graphql

我已经编写了一个软件,该软件可以解析并格式化graphql解析器函数(信息对象)的第四个参数,以在其他地方使用。我想为此软件编写单元测试。具体来说,我不想自己构建GraphQLResolveInfo对象,因为这样做会很麻烦,容易出错并且难以维护。相反,我想编写人类可读的查询字符串并将其转换为GraphQLResolveInfo对象,以便将其传递给软件。

在广泛地搜索和阅读graphql-js源代码之后,我还没有找到一种简单的方法来完成他们内部的工作。我真的很希望我能缺少一些东西。

我不打算使用graphql-tag库,因为它只会生成一个AST,其格式与GraphQLResolveInfo类型非常不同。

有人做过吗?帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我将继续监视此问题以查看是否有更好的答案,但是我终于设法通过创建特定用途的GraphQLResolveInfo对象的近似值来解决我的特定问题情况。

GraphQLResolveInfo对象由多个属性组成,其中两个属性分别称为fieldNodesfragments。实际上,两者都是graphql-tag从查询字符串生成的同一AST的一部分。这些是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);

graphql-tag生成的AST中,我提取并修改操作和片段定义,以使它们看起来像在GraphQLResolveInfo对象中的操作方式一样。这绝不是完美的,并且将来可能会有所变化,具体取决于我的软件如何发展,但这对于我的特定问题来说是一个相对简短的解决方案。