GraphQL - 示例
GraphQL - 基础服务器示例
Section titled “GraphQL - 基础服务器示例”在本章中,我们将使用现代工具构建一个最小但功能完整的 GraphQL API。这个 API 将返回一个简单的问候消息 ‘Hello GraphQL World!’,我们将使用 Apollo Sandbox(一个浏览器内的 GraphQL IDE)访问它。
创建一个独立的 GraphQL 服务器,使用 Node.js、Express 和 Apollo Server 4,响应一个简单的 greeting 查询。
使用的核心概念
Section titled “使用的核心概念”- Node.js: JavaScript 运行时环境。
- Express: 用于 Node.js 的极简 Web 应用框架。
- @apollo/server: 构建 GraphQL 服务器的核心库。
- graphql: GraphQL 的 JavaScript 参考实现。
- Schema Definition Language (SDL): 用于定义 API 的结构。
- Resolvers: 为 Schema 字段提供数据的函数。
第一步:项目设置和依赖
Section titled “第一步:项目设置和依赖”创建一个新的项目文件夹(例如 hello-graphql-server)并初始化它:
mkdir hello-graphql-servercd hello-graphql-servernpm init -y安装必要的依赖:
npm install @apollo/server graphql express cors body-parser这将安装 Apollo Server 4、GraphQL.js、Express,以及用于 CORS 和 JSON 请求体解析的中间件。
第二步:定义 Schema
Section titled “第二步:定义 Schema”定义你的 GraphQL Schema。为了简单起见,我们将直接在服务器文件中将其定义为一个字符串。在大型项目中,通常会将其放在单独的 .graphql 文件中。
// In server.js (or a separate schema.js file)// 在 server.js (或单独的 schema.js 文件) 中const typeDefs = `#graphql # This "Query" type defines all the available entry points for reading data. # "Query" 类型定义了所有可用的数据读取入口点。 type Query { # This query takes no arguments and returns a String # 这个查询不接受参数并返回一个 String 类型的值 greeting: String }`;这个 Schema 定义了一个名为 greeting 的查询字段,它返回一个非空的 String 类型值。
第三步:创建 Resolvers
Section titled “第三步:创建 Resolvers”Resolvers(解析器)是为 Schema 中的字段提供实际数据的函数。解析器对象的结构应镜像 Schema 的结构。
// In server.js (or a separate resolvers.js file)// 在 server.js (或单独的 resolvers.js 文件) 中const resolvers = { // Resolvers for the Query type // Query 类型的解析器 Query: { // Resolver function for the 'greeting' field // 'greeting' 字段的解析器函数 greeting: () => { // This function simply returns the string we want // 这个函数只返回我们想要的字符串 return 'Hello GraphQL World!'; }, },};这个解析器对象为 Query 类型中的 greeting 字段提供了一个函数。
第四步:使用 Express 设置 Apollo Server
Section titled “第四步:使用 Express 设置 Apollo Server”创建一个 server.js 文件(如果尚未创建),并组合 Schema、Resolvers 和服务器设置:
import { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import express from 'express';import http from 'http';import cors from 'cors';import bodyParser from 'body-parser';
// Define Schema (as shown in Step 2)// 定义 Schema(如第二步所示)const typeDefs = `#graphql type Query { greeting: String }`;
// Define Resolvers (as shown in Step 3)// 定义 Resolvers(如第三步所示)const resolvers = { Query: { greeting: () => 'Hello GraphQL World!', },};
// Required logic for integrating with Express// 与 Express 集成所需的逻辑const app = express();// Our httpServer handles incoming requests to our Express app.// 我们的 httpServer 处理进入 Express 应用的请求。// Below, we drain the httpServer when the application is shut down.// 下面,我们在应用关闭时“排出”httpServer。const httpServer = http.createServer(app);
// Same ApolloServer initialization as before, plus the drain plugin// 与之前相同的 ApolloServer 初始化,加上用于 httpServer 的 drain 插件。// for our httpServer.const server = new ApolloServer({ typeDefs, resolvers, plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],});
// Ensure we wait for our server to start// 确保我们等待服务器启动await server.start();
// Set up our Express middleware to handle CORS, body parsing,// 设置我们的 Express 中间件来处理 CORS、请求体解析,// and our expressMiddleware function.// 以及我们的 expressMiddleware 函数。app.use( '/graphql', // Endpoint path for GraphQL requests // GraphQL 请求的接口路径 cors(), // Enable Cross-Origin Resource Sharing // 启用跨域资源共享 bodyParser.json(), // Parse JSON bodies // 解析 JSON 请求体 // expressMiddleware accepts the same arguments: an Apollo Server instance and optional configuration options // expressMiddleware 接受相同的参数:一个 Apollo Server 实例和可选的配置选项 expressMiddleware(server, { context: async ({ req }) => ({ token: req.headers.token }), // Example context // 示例 context }),);
const PORT = process.env.PORT || 9000;
// Modified server startup// 修改后的服务器启动逻辑await new Promise((resolve) => httpServer.listen({ port: PORT }, resolve));
console.log(`🚀 Server ready at http://localhost:${PORT}/graphql`);这段代码初始化了 Express,创建了一个 HTTP 服务器,使用 Schema 和 Resolvers 设置了 Apollo Server,应用了必要的中间件(CORS、JSON 解析),并使用 expressMiddleware 将 Apollo Server 集成到 Express 的 /graphql 路径下。
第五步:启动应用
Section titled “第五步:启动应用”将启动脚本添加到你的 package.json 中(如果尚未添加):
"scripts": { "start": "node server.js" // Requires Node.js v14.13.1+ for top-level await or wrap in async function // 需要 Node.js v14.13.1+ 支持顶层 await,否则需要将其包裹在 async 函数中}在终端中运行服务器:
npm start你应该看到消息:🚀 Server ready at http://localhost:9000/graphql
第六步:测试 GraphQL API
Section titled “第六步:测试 GraphQL API”打开你的 Web 浏览器,导航到 http://localhost:9000/graphql。
这将打开 Apollo Sandbox,一个类似于 GraphiQL 的工具,允许你与你的 API 交互。
在左侧面板(Operation panel)中,输入以下 GraphQL 查询:
query MyFirstQuery { greeting}点击“Run”或“Execute Query”按钮(通常看起来像播放图标)。
在右侧面板(Response panel)中,你应该看到来自服务器的结果:
{ "data": { "greeting": "Hello GraphQL World!" }}恭喜!你已成功构建并测试了一个基础的 GraphQL 服务器。