GraphQL 服务器的结构和实现(第二部分)。
在上一篇文章中,我们通过了解 GraphQL 模式及其在执行查询和变更时的基本作用,涵盖了 GraphQL 服务器内部工作原理的许多方面。
虽然我们了解了 GraphQL 服务器如何使用GraphQL 引擎执行这些操作,但我们还没有涉及实际的客户端-服务器通信方面:查询及其响应如何在网络上传输的问题。这就是本文要讲的内容!
GraphQL 服务器可以使用您首选的任何编程语言来实现。本文重点介绍 JavaScript 以及可用于构建服务器的可用库,最值得注意的是:
express-graphql
、apollo-server
和graphql-yoga
。
通过 HTTP 提供 GraphQL
GraphQL 与传输层无关
关于 GraphQL,需要理解的关键一点是,它实际上与数据在网络上的传输方式无关。这意味着 GraphQL 服务器有可能基于 HTTP 以外的协议工作,例如 WebSockets 或更底层的 TCP。但是,本文重点介绍当今实现 GraphQL 服务器的最常见方式,它确实基于 HTTP。
Express.js 用作强大而灵活的基础
以下部分主要介绍 Express.js 及其中间件概念,这些中间件用于诸如
express-graphql
和apollo-server
等 GraphQL 库。如果您已经熟悉 Express,则可以跳到下一部分。
express、hapi、koa 和 sail 在 npm 趋势上的比较
Express.js 是迄今为止最受欢迎的 JavaScript Web 框架。它以其简单性、灵活性和性能而著称。
您只需要以下代码即可开始使用自己的 Web 服务器
使用 Node.js 执行此脚本后,您可以在浏览器中访问 https://127.0.0.1:3000
上的网站
您可以轻松地向服务器的 API 添加更多端点(也称为路由)
或者使用另一个 HTTP 方法,例如 POST 而不是 GET
Express 在实现服务器方面提供了极大的灵活性,允许您使用 中间件 的概念轻松添加功能。
Express 中灵活性和模块化的关键:中间件
中间件允许拦截传入的请求并执行专用任务,同时处理请求或在返回响应之前。
本质上,中间件只是一个接受三个参数的函数
req
:来自客户端的传入请求res
:要返回给客户端的响应next
:用于调用下一个中间件的函数
由于中间件函数具有(写入)访问传入请求对象和传出响应对象的权限,因此它们是一个非常强大的概念,可以根据特定目的塑造请求和响应。
中间件可用于许多用例,例如身份验证、缓存、数据转换和验证、执行自定义业务逻辑等等。以下是一个简单的日志记录示例,它将打印收到请求的时间
诸如 graphql-express
、apollo-server
或 graphql-yoga
等框架利用了通过这种中间件方法获得的灵活性,这些框架都基于 Express!
Express 和 GraphQL
凭借我们在上一篇文章中了解到的关于 graphql
函数和一般 GraphQL 执行引擎的所有内容,我们已经可以预料到基于 Express 的 GraphQL 服务器如何工作。
由于 Express 提供了处理 HTTP 请求所需的一切,而 GraphQL.js 提供了用于解析查询的功能,因此我们仍然需要的只是它们之间的粘合剂。
诸如 express-graphql
和 apollo-server
等库提供了这种粘合剂,它们只是 Express 的中间件函数!
GraphQL 中间件将 HTTP 和 GraphQL.js 粘合在一起
express-graphql
:Facebook 的 GraphQL 中间件版本
express-graphql
是 Facebook 的 GraphQL 中间件版本,可与 Express 和 GraphQL.js 一起使用。如果您查看其源代码,您会注意到其核心功能仅用几行代码实现。
实际上,它的主要职责是双重的
- 确保 GraphQL.js 可以执行传入 POST 请求正文中包含的 GraphQL 查询(或变更)。因此,它需要解析出查询并将其转发到
graphql
函数进行执行。 - 将执行结果附加到响应对象,以便将其返回给客户端。
使用 express-graphql
,您可以快速启动 GraphQL 服务器,如下所示
使用 Node.js 执行此代码会在
https://127.0.0.1:4000/graphql
上启动 GraphQL 服务器
如果您阅读了关于 GraphQL 模式的上一篇文章,您将很好地理解第 7 至 18 行的用途:我们构建了一个可以执行以下查询的 GraphQLSchema
这段代码片段的新部分是集成的网络层。我们不再像这里演示的那样,直接内联编写查询并使用 GraphQL.js 执行它,这次我们只是设置服务器等待传入的查询,然后可以针对 GraphQLSchema
执行这些查询。
你真的不需要太多东西就可以开始在服务器端使用 GraphQL。
apollo-server
: 在 Express 生态系统之外具有更好的兼容性
本质上,apollo-server
与 express-graphql
非常相似,只有一些细微的差别。两者之间的主要区别在于,apollo-server
还允许与许多其他框架集成,例如 koa
和 hapi
,以及与 AWS Lambda 或 Azure Functions 等 FaaS 提供商集成。每个集成都可以通过在包名称后附加相应的后缀来安装,例如 apollo-server-express
、apollo-server-koa
或 apollo-server-lambda
。
然而,核心上它也只是一个中间件,将 HTTP 层与 GraphQL.js 提供的 GraphQL 引擎桥接起来。以下是使用 apollo-server-express
实现的上述基于 express-graphql
的示例的等效实现:
graphql-yoga
:构建 GraphQL 服务器的最简单方法
在构建 GraphQL 服务器时消除摩擦
即使使用 express-graphql
或 apollo-server
,也存在各种摩擦点:
- 需要安装多个依赖项
- 假设预先了解 Express
- 使用 GraphQL 订阅的设置复杂
graphql-yoga
消除了这种摩擦,它是一个用于构建 GraphQL 服务器的简单库。它本质上是 Express、apollo-server
和一些其他库之上的便利层,提供了一种创建 GraphQL 服务器的快速方法。(可以将其视为 GraphQL 服务器的create-react-app。)
以下是我们在 express-graphql
和 apollo-server
中看到的相同 GraphQL 服务器的样子:
请注意,可以使用 GraphQLSchema
的就绪实例实例化 GraphQLServer
,也可以使用便利 API(基于 graphql-tools
中的 makeExecutableSchema
),如上面的代码片段所示。
内置支持 GraphQL Playgrounds、订阅和追踪
请注意,graphql-yoga
还内置了对 graphql-playground
的支持。使用上面的代码,你可以在 https://127.0.0.1:4000
打开 Playground。
graphql-yoga
还提供了一个开箱即用的 GraphQL 订阅的简单 API,它建立在 graphql-subscriptions
和 ws-subscriptions-transport
包之上。你可以在这个简单的示例中查看其工作原理。
要为使用 graphql-yoga
执行的 GraphQL 操作启用字段级分析,还内置了对Apollo Tracing的支持。
结论
在上一篇文章中讨论了基于GraphQLSchema
的 GraphQL 执行过程和 GraphQL 引擎的概念(例如GraphQL.js)之后,这次我们专注于网络层。特别是,GraphQL 服务器如何通过使用执行引擎处理查询(或突变)来响应 HTTP 请求。
在 Node 生态系统中,Express 因其简单性和灵活性而成为构建 Web 服务器的最受欢迎的框架。因此,GraphQL 服务器最常见的实现基于 Express,最著名的是express-graphql
和 apollo-server
。这两个库非常相似,只有一些细微的差别,其中最重要的是 apollo-server
还与其他 Web 框架(如 koa
和 hapi
)兼容。
graphql-yoga
是许多其他库(如 graphql-tools
、express
、graphql-subscriptions
和 graphql-playground
)之上的便利层,是构建 GraphQL 服务器的最简单方法。
在下一篇文章中,我们将讨论传递到 GraphQL 解析器中的 info
参数的内部结构。
不要错过下一篇文章!
注册 Prisma 新闻通讯