随着现代 Web 应用程序对 API 数量、性能和可扩展性的要求越来越高,GraphQL、Node.js 和 Apollo Server 成为构建高效的服务器端应用程序的技术之一。本文将介绍如何使用 Apollo Server 和 GraphQL,构建高效的 Node.js 服务器。
什么是 Apollo Server?
Apollo Server 是一个用于构建 GraphQL API 的库。它是基于 Node.js 平台中最流行的开发框架之一,express的基础上构建的。它支持多种数据源,包括数据库、REST API、服务间通信等等。而且它也支持多语言,如 JavaScript、TypeScript、Go、Java、Scala 等等。
什么是 GraphQL?
GraphQL 是一种用于构建 API 的查询语言,由Facebook在2012年提出,它提供了一种更高效、强大、灵活和可定制化的方式来请求数据。GraphQL 真正的优势在于它允许客户端定义数据的结构及其关系,而不是从服务器端获取预定义的数据结构。因此,GraphQL API 可以精确地提供客户端请求的数据,从而提高了应用程序的性能。
安装并设置 Apollo Server
首先,我们需要全局安装 nodemon
依赖:
--- - -- -------
接着,我们新建一个项目并安装相关依赖:
----- --------------------- -- --------------------- --- ---- -- --- - ------------- -------
接下来,我们设置 Apollo Server。创建一个新文件, server.js
:
----- - ------------- --- - - ------------------------- ----- -------- - ---- ---- ----- - ------ ------ - -- ----- --------- - - ------ - ------ -- -- ------ -------- -- -- ----- ------ - --- -------------- --------- --------- --- ----------------------- --- -- -- - --------------- ------ ----- -- --------- ---
创建一个用于定义 schema 的变量 typeDefs
,并用于定义 Query Resolver 的变量 resolvers
。接着,我们将它们传入 ApolloServer
中,然后监听在本地的默认端口 4000
。
运行:
------- ---------
现在访问 http://localhost:4000/graphql 地址就可以打开 GraphQL Playground。
查询和变异(Query and Mutation)
查询
最简单的查询是指定其名字:
----- - ----- -
这将返回:
- ------- - -------- ------ ------- - -
变异
我们可以定义一个简单的变异,它将把两个整数加起来:
----- -------- - ---- ---- ----- - ------ ------ ------ ----- -- ------ --- - ---- -------- - -------------- --------- ------ - -- ----- --------- - - ------ - ------ -- -- ------ -------- ---- -------- - -- - -- -- - - -- -- --------- - --------- -------- - ---- -- -- ------ ---------- -- --
我们定义了名为 sum
的查询与名为 sayHello
的变异。现在,我们可以这样查询:
----- - ------ -- -- -- - -------- - -------------- -------- -
这样将返回:
- ------- - ------ - - -
- ------- - ----------- ------ ------- - -
数据源
我们可以使用 REST API、数据库、JavaScript 对象数组和运行在其他服务器上的其他服务作为我们的 GraphQL API 数据源。这里我们使用一个伪造的数据库情况——并且,这也是内存数据源池的情况。
首先,让我们声明两个数据模型:
----- ----- - - - --- ---- ----- ------- ------- ------- --- -- - --- ---- ----- -------- ------- ------- --- -- - --- ---- ----- ------ -------- ------- --- -- -- ----- ----- - - - --- ---- ----- ---- ------- ------- -- - --- ---- ----- ------- ----- --------- -- - --- ---- ----- --------- ----- -- -- ----- -------- - ---- ---- ----- - -------- ----- ---- ------ ------- -------- ----- ---- ------ ------- - ---- -------- - ---------------- -------- ------- --------- ----- - ---- ---- - --- --- ----- ------- ----- ----- - ---- ---- - --- --- ----- ------- -------- ------- - --
users
数组用于存储用户的数据(id,姓名,所属团队的id),teams
数组用于存储队伍的数据(id,名称)。
这是我们的查询解析器的实现:
----- --------- - - ------ - ----- -------- - -- -- -- ----------------- -- ------- --- ---- ------ -- -- ------ ----- -------- - -- -- -- ----------------- -- ------- --- ---- ------ -- -- ------ -- --------- - ----------- -------- - ----- ------ -- -- - ----- ---- - - --- ------------------- - --- ----- ------ -- ----------------- ------ ----- -- -- ----- - ----- -------- -- ----------------- -- ------- --- --------------- -- ----- - -------- -------- -- ------------------- -- ----------- --- ----------- -- --
我们自定义了 User
和 Team
类型的解析器。User
解析器获取与该用户关联的队伍;Team
解析器获取与该团队关联的所有成员。
现在,我们可以查询所有用户、所有团队、指定的用户或团队。
在GraphQL Playground中,我们输入以下内容:
----- - -------- ---- - ---- ---- - ---- - - ----- - -- ---- ---- - ---- - - -------- ---- - ---- ------- - ---- - - ----- - -- ---- ------- - ---- - - - -------- - ---------------- ------ ------ ------- ---- - ---- ---- - ---- - - -
这将返回:
- ------- - ------- - ------- ------- ------- ------- - ------- ---- ------- ------- - -- -------- - - ----- ---- ------- ------- ------- ------- - ------- ---- ------- ------- - -- - ----- ---- ------- -------- ------- ------- - ------- ------- ----- --------- - -- - ----- ---- ------- ------ -------- ------- - ------- --------- ----- - - -- ------- - ------- ---- ------- -------- ---------- - - ------- ------- ------ -- - ------- ------ ----- - - -- -------- - - ----- ---- ------- ---- ------- -------- ---------- - - ------- ------- ------ -- - ------- ------ ----- - - -- - ----- ---- ------- ------- ----- ---------- ---------- - - ------- -------- ------ - - -- - ----- ---- ------- --------- ------ ---------- - - ------- ------ ------- - - - - - -
- ------- - ------------- - ------- ------ ------ ------- - ------- ---- ------- ------- - - - -
现在我们需要将 Apollo Server 中的伪造数据替换为从数据库获取数据的方式。
----- - ------------- --- - - ------------------------- ----- -------- - -------------------- ----------------------------------------------------------------------------------------------------------------- - ---------------- ----- ------------------- ---- -- -------- -- - -------------- --------- -- ---------- -- ------------ -- - -------------------- ---------- -- ---------- ----- --- -- ---- ----- ---------- - --- ----------------- ----- - ----- ------- --------- ---- -- ------- - ----- ------- --------- ---- -- --- ----- ---------- - --- ----------------- ----- - ----- ------- --------- ---- -- --- -- -- ----- --------- - ---------------------- ------------ ----- --------- - ---------------------- ------------ -- --------- --------- - ----- ------ - --- -------------- --------- ---------- -------- -- -- -- ---------- ---------- --- --- ------ --------- -------- --- -- -- -------------- ------ --------- -- --------- ------------ -- --------------------
我们使用 Mongoose 在 MongoDB 中定义了 User
和 Team
模型。现在,我们需要将模型传递给 Apollo Server 的 context
选项。
接下来我们来调整查询和解析器,使其适应 MongoDB 并插入初始的几条数据:
----- --------- - - ------ - ----- -------- - -- -- - --------- -- -- ----------------------- ------ -------- ----- - --------- -- -- ----------------- ----- -------- - -- -- - --------- -- -- ----------------------- ------ -------- ----- - --------- -- -- ----------------- -- --------- - ----------- -------- ----- - --------- -- -- - ----- ---- - --- ---------------- ------ ------------ -- -- ----- - ----- ----- -------- ----- - --------- -- -- - ------ ----- ---------------------------------- -- -- ----- - -------- ----- -------- ----- - --------- -- -- - ------ ----- ---------------- ------- --------- --- -- -- -- -- ----- ----- ---- - ----- -- -- - ----- ---------------------- - ----- ---- ------- ------- -- - ----- ------- ----- --------- -- - ----- --------- ----- -- --- ----- ----- - ----- ----------------- ----- ---------------------- - ----- ------- ------- ------- ------------ -- - ----- -------- ------- ------- ------------ -- - ----- ------ -------- ------- ------------ -- --- -- -------
现在,我们可以查询所有用户、所有团队、指定的用户或团队。而且,相比于我们之前在内存中伪造数据进行的操作,我们现在引入了 MongoDB 数据库。
在GraphQL Playground中,我们输入以下内容:
----- - -------- ------------ - ---- ---- - ---- - - ----- - -- ---- ---- - ---- - - -------- ------------ - ---- ------- - ---- - - ----- - -- ---- ------- - ---- - - - -------- - ---------------- ------ ------ ------- ------------ - ---- ---- - ---- - - -
结论
在本文中,我们以 Apollo Server 和 GraphQL 为基础介绍了如何构建高效的 Node.js 服务器。我们开始学习如何设置 Apollo Server,如何定义和解析器和查询和变异。随后,我们以不同的数据源为基础,演示了其查询和变异的用法以及它们的解析器。最后,我们把内存数据持久化到了 MongoDB 中。
GraphQL 是一个出色的解决方案,如果你想构建强壮、高效并且可扩展的 API,考虑使用它。而 Apollo Server 则是它的首选实现,因为具备极高的灵活性和可扩张性。
完整代码:
----- - ------------- --- - - ------------------------- ----- -------- - -------------------- -- -- ------- --- ----------------------------------------------------------------------------------------------------------------- - ---------------- ----- ------------------- ---- -- -------- -- - -------------- --------- -- ---------- -- ------------ -- - -------------------- ---------- -- ---------- ----- --- -- ---- ----- ---------- - --- ----------------- ----- - ----- ------- --------- ---- -- ------- - ----- ------- --------- ---- -- --- ----- ---------- - --- ----------------- ----- - ----- ------- --------- ---- -- --- -- -- ----- --------- - ---------------------- ------------ ----- --------- - ---------------------- ------------ ----- -------- - ---- ---- ----- - -------- ----- ---- ------ ------- -------- ----- ---- ------ ------- - ---- -------- - ---------------- -------- ------- --------- ----- - ---- ---- - --- --- ----- ------- ----- ----- - ---- ---- - --- --- ----- ------- -------- ------- - -- ----- --------- - - ------ - ----- -------- - -- -- - --------- -- -- ----------------------- ------ -------- ----- - --------- -- -- ----------------- ----- -------- - -- -- - --------- -- -- ----------------------- ------ -------- ----- - --------- -- -- ----------------- -- --------- - ----------- -------- ----- - --------- -- -- - ----- ---- - --- ---------------- ------ ------------ -- -- ----- - ----- ----- -------- ----- - --------- -- -- - ------ ----- ---------------------------------- -- -- ----- - -------- ----- -------- ----- - --------- -- -- - ------ ----- ---------------- ------- --------- --- -- -- -- ----- ------ - --- -------------- --------- ---------- -------- -- -- -- ---------- ---------- --- --- -- ----- ----- ---- - ----- -- -- - ----- ---------------------- - ----- ---- ------- ------- -- - ----- ------- ----- --------- -- - ----- --------- ----- -- --- ----- ----- - ----- ----------------- ----- ---------------------- - ----- ------- ------- ------- ------------ -- - ----- -------- ------- ------- ------------ -- - ----- ------ -------- ------- ------------ -- --- -- ------- ------ --------- -------- --- -- -- -------------- ------ --------- -- --------- ------------ -- --------------------
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/672b3978ddd3a70eb6d23305