gql 和 buildSchema 有啥区别?

Posted

技术标签:

【中文标题】gql 和 buildSchema 有啥区别?【英文标题】:What is the difference between gql and buildSchema?gql 和 buildSchema 有什么区别? 【发布时间】:2021-07-29 19:06:46 【问题描述】:

graphql-js buildSchema 和 apollo-server gql 有什么区别?他们似乎做着非常相似的工作。

【问题讨论】:

您是否阅读过有关gql 和buildSchema 的文档 【参考方案1】:

首先注意,apollo-server 的gql 实际上是从graphql-tag 重新导出的。 graphql-tag 是一个约 150 行的包,默认的并且几乎唯一有用的导出是 gql

背景知识简介:graphql-js 包提供了 GraphQL 的官方参考实现在 javascript 中。它基本上提供了两个重要的东西:

    graphql 函数,它将处理针对 GraphQLSchema 对象的任何 GraphQL 查询(GraphQLSchema 对象是 graphql-js 表示已解析架构的方式)。 一组实用函数和类型,用于从字符串中构建和验证 graphql 函数使用的 GraphQLSchema 对象。

现在,这是最终让我感到困惑的部分:在graphql-js 中,将字符串转换为GraphQLSchema 对象是一个两步过程:

第 1 步:字符串 -> AST(由 parse 函数完成)。 第 2 步:AST -> GraphQLSchema(由 buildASTSchema 函数完成)。

这是因为 AST(抽象语法树)对许多其他工具很有用,这些工​​具甚至不一定了解 GraphQL(例如参见https://astexplorer.net/),而 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 不会直接返回 GraphQLSchema ,原因如上所述:AST 很有用(注意 gql 也在做一些基本的事情,比如状态缓存,并将模式字符串数组合并到单个 AST 结果中。 ..)。不过最终必须将 AST 转换为正确的模式,而 apollo-server 在服务器实例化时会执行此操作(大概)。

为了显示这种关系,我们可以将gql 的输出(与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!'  

【讨论】:

以上是关于gql 和 buildSchema 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

字符串插值和片段之间有啥显着区别吗?

build.sbt 和 build.scala 有啥区别?

Fastlane/Scanfile 上的 Skip_build 和 test_without_building 有啥区别

schema.graphql 与 buildSchema()

您在 Google App Engine 上进行开发有啥经验?

新 GraphQL buildSchema 的嵌套查询