gql 和 buildSchema 有什么区别?
What is the difference between gql and buildSchema?
graphql-js buildSchema
and the apollo-servergql
有什么区别?他们的工作似乎非常相似。
首先请注意,apollo-server 的 gql
实际上是从 graphql-tag 重新导出的。 graphql-tag
是一个约 150 行的包,默认且几乎唯一有用的导出是 gql
。
快速背景知识:graphql-js
包在 Javascript 中提供了 GraphQL 的官方参考实现。它基本上提供了两个重要的东西:
graphql
函数,它将处理针对 GraphQLSchema
对象的任何 GraphQL 查询(GraphQLSchema 对象是 graphql-js 表示已解析模式的方式)。
- 一堆实用函数和类型,用于从字符串构建和验证
graphql
函数使用的 GraphQLSchema
对象。
现在,这是最终让我感到困惑的部分:在graphql-js
中,获取一个字符串并将其转换为一个GraphQLSchema
对象是两个步骤过程:
- 第 1 步:字符串 -> AST(由
parse
函数完成)。
- 第 2 步:AST -> GraphQLSchema(由
buildASTSchema
函数完成)。
之所以这样是因为 AST(抽象语法树)对许多其他工具很有用,这些工具甚至不一定了解 GraphQL(例如参见 [=37=]),而 GraphQLSchema仅对graphql-js及相关软件有意义
graphql-js 公开了执行这两个步骤的函数,这些函数被下游实现者(如 Apollo)重用。 buildSchema
只是组合这两个步骤的便利包装器。这是 literally this:
/**
* 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-js parse
函数的输出相同。 gql
不直接 return 和 GraphQLSchema
是因为上面提到的原因:AST 很有用(注意 gql
也在做一些基本的事情,比如有状态缓存,并将合并一个将模式字符串数组转换为单个 AST 结果 ...)。最终 AST 将不得不变成一个合适的模式,而 apollo-server 在服务器被实例化时会这样做(大概)。
为了显示关系,我们可以通过 buildASTSchema
获取 gql
(与 parse
相同)运行 的输出(就像 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!' } }
graphql-js buildSchema
and the apollo-servergql
有什么区别?他们的工作似乎非常相似。
首先请注意,apollo-server 的 gql
实际上是从 graphql-tag 重新导出的。 graphql-tag
是一个约 150 行的包,默认且几乎唯一有用的导出是 gql
。
快速背景知识:graphql-js
包在 Javascript 中提供了 GraphQL 的官方参考实现。它基本上提供了两个重要的东西:
graphql
函数,它将处理针对GraphQLSchema
对象的任何 GraphQL 查询(GraphQLSchema 对象是 graphql-js 表示已解析模式的方式)。- 一堆实用函数和类型,用于从字符串构建和验证
graphql
函数使用的GraphQLSchema
对象。
现在,这是最终让我感到困惑的部分:在graphql-js
中,获取一个字符串并将其转换为一个GraphQLSchema
对象是两个步骤过程:
- 第 1 步:字符串 -> AST(由
parse
函数完成)。 - 第 2 步:AST -> GraphQLSchema(由
buildASTSchema
函数完成)。
之所以这样是因为 AST(抽象语法树)对许多其他工具很有用,这些工具甚至不一定了解 GraphQL(例如参见 [=37=]),而 GraphQLSchema仅对graphql-js及相关软件有意义
graphql-js 公开了执行这两个步骤的函数,这些函数被下游实现者(如 Apollo)重用。 buildSchema
只是组合这两个步骤的便利包装器。这是 literally this:
/**
* 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-js parse
函数的输出相同。 gql
不直接 return 和 GraphQLSchema
是因为上面提到的原因:AST 很有用(注意 gql
也在做一些基本的事情,比如有状态缓存,并将合并一个将模式字符串数组转换为单个 AST 结果 ...)。最终 AST 将不得不变成一个合适的模式,而 apollo-server 在服务器被实例化时会这样做(大概)。
为了显示关系,我们可以通过 buildASTSchema
获取 gql
(与 parse
相同)运行 的输出(就像 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!' } }