graphql-js buildSchema
和apollo-server 有什么区别gql
?他们似乎做着非常相似的工作。
1 回答
首先请注意, apollo-server实际上是从graphql-taggql
重新导出的。是一个约 150 行的包,它是默认的并且几乎唯一有用的导出是.graphql-tag
gql
快速了解一下背景:该graphql-js
包提供了 GraphQL 在 Javascript 中的官方参考实现。它基本上提供了两个重要的东西:
- 该
graphql
函数将处理针对GraphQLSchema
对象的任何 GraphQL 查询(GraphQLSchema 对象是 graphql-js 表示您解析的模式的方式)。 - 一堆实用函数和类型,用于从字符串构建和验证函数
GraphQLSchema
使用的对象。graphql
现在,这是最终让我感到困惑的部分:在 中graphql-js
,将字符串转换为GraphQLSchema
对象是一个两步过程:
- 第 1 步:字符串 -> AST(由
parse
函数完成)。 - 第 2 步:AST -> GraphQLSchema(由
buildASTSchema
函数完成)。
之所以这样,是因为 AST(抽象语法树)对许多其他工具很有用,这些工具甚至不一定了解 GraphQL(例如参见https://astexplorer.net/),而 GraphQLSchema 只是对graphql-js及相关软件有意义。
graphql-js 公开了执行这两个步骤的函数,并且这些函数被下游实现者(如 Apollo)重用。buildSchema
只是结合这两个步骤的便利包装器。字面意思是这样的:
/**
* A helper function to build a GraphQLSchema directly from a source
* document.
*/
export function buildSchema(source: string | Source): GraphQLSchema {
return buildASTSchema(parse(source));
}
gql
另一方面,输出只是 AST 部分,与 graphql-jsparse
函数的输出相同。由于上述原因,gql
不直接返回 a :AST 很有用(注意还做了一些基本的事情,比如有状态缓存,并将模式字符串数组合并到单个 AST 结果中......)。最终,AST 必须转换为适当的模式,而 apollo-server 在服务器实例化时(可能)会这样做。GraphQLSchema
gql
为了显示这种关系,我们可以将gql
(same as parse
) 的输出运行它buildASTSchema
(就像buildSchema
那样),然后将它传递给它graphql
,它的工作原理是一样的:
import { graphql, buildSchema, buildASTSchema } from 'graphql';
import { gql } from 'apollo-server'; // equivalent to 'import gql from graphql-tag'
const schemaString = `
type Query {
hello: String!
}
`;
const a = buildASTSchema(gql(schemaString));
const b = buildSchema(schemaString);
graphql(a, '{ hello }', { hello: () => 'Hello world!' }).then((response) => {
console.log(response);
});
graphql(b, '{ hello }', { hello: () => 'Hello world!' }).then((response) => {
console.log(response);
});
给出:
{ data: [Object: null prototype] { hello: 'Hello world!' } }
{ data: [Object: null prototype] { hello: 'Hello world!' } }