加入我们,从10月8日至10日在纽约市,学习关于GraphQL联盟和API平台工程的最新的技巧、趋势和新闻。加入我们,在纽约市2024年的GraphQL峰会
文档
免费开始

教MERN堆栈说GraphQL


是为与MERN堆栈(MongoDB、Express、React、Node)应用程序无缝工作而设计的。本教程展示了如何将Apollo Server添加到现有的MERN堆栈项目中。具体来说,本教程演示了如何:

  • 运行一个 Apollo Server 实例,让您执行 s
  • 在MERN堆栈应用程序中公开一个 GraphQL 路线

先决条件

本教程假设您熟悉命令行和JavaScript。此外,还需要以下条件

  • 您已安装最新的Node.js版本(v14.16.0+
  • 您已完成MongoDB的MERN堆栈教程,或者您有现有的MERN堆栈应用程序。
    • 本教程的代码示例基于教程,但您可以根据应用程序的要求对其进行修改。
  • 您有一个具有records集合的MongoDB数据库,该集合具有namepositionlevel列。
    • 本教程的代码示例使用这些列名,但您可以根据数据库的模式进行修改。

步骤 1:安装依赖项

在您的服务器文件夹中,运行以下命令以安装这些包并将它们保存到您的服务器项目的node_modules目录中:

npm install graphql graphql-tag @apollo/subgraph @apollo/server
  • graphqlGraphQL的JavaScript参考实现
  • graphql-tag是一个工具包,可将GraphQL字符串解析为标准的GraphQL抽象语法树(AST)
  • @apollo/subgraph是一个工具包,可创建GraphQL微服务
  • @apollo/server是一个符合规范的,它公开了/graphql端点

步骤 2:定义您的GraphQL模式

每一个GraphQL服务器(包括Apollo Server)都使用一个模式来定义客户端可以的数据。以下示例为前置教程'的记录

在您的服务器的/src文件夹中,创建一个schema.graphql文件,并粘贴以下模式:

type Query {
record(id:ID!): Record
records: [Record]
}
type Mutation {
createRecord(name: String!, position: String, level: String): Record
deleteRecord(id: ID!): Boolean
updateRecord(id: ID! name: String, position: String, level: String): Record
}
type Record {
id: ID
name: String
position: String
level: String
}

此模式允许您对记录执行各种操作:获取单个或多个记录、创建新记录、删除记录以及更新现有记录。有关模式定义的更多信息,请参阅模式基础文档。

步骤 3:定义解析器

函数负责执行在模式中定义的操作——例如,获取和更新记录。在一个MERN堆栈应用程序中,它们是将与您的MongoDB实例连接的方式。

在您的服务器的/src文件夹中,创建一个新的resolvers.js文件,并粘贴以下

import db from "./db/connection.js";
const resolvers = {
Record: {
id: (parent) => parent.id ?? parent._id,
},
Query: {
async record(_, { id }) {
let collection = await db.collection("records");
let query = { _id: new ObjectId(id) };
return await collection.findOne(query);
},
async records(_, __, context) {
let collection = await db.collection("records");
const records = await collection.find({}).toArray();
return records;
},
},
Mutation: {
async createRecord(_, { name, position, level }, context) {
let collection = await db.collection("records");
const insert = await collection.insertOne({ name, position, level });
if (insert.acknowledged)
return { name, position, level, id: insert.insertedId };
return null;
},
async updateRecord(_, args, context) {
const id = new ObjectId(args.id);
let query = { _id: new ObjectId(id) };
let collection = await db.collection("records");
const update = await collection.updateOne(
query,
{ $set: { ...args } }
);
if (update.acknowledged)
return await collection.findOne(query);
return null;
},
async deleteRecord(_, { id }, context) {
let collection = await db.collection("records");
const dbDelete = await collection.deleteOne({ _id: new ObjectId(id) });
return dbDelete.acknowledged && dbDelete.deletedCount == 1 ? true : false;
},
},
};
export default resolvers;

你可能已经注意到了每个的代码,与你的应用程序中/record路由处的代码相似。这是因为这些解析器提供了与在集合上执行CRUD相同的逻辑。

要了解更多关于编写解析器函数的信息,请参阅解析器文档

第4步:将Apollo Server添加到你的Express服务器

现在可以将Apollo Server集成到你的Express服务器中。无论你在哪里实例化你的express服务器(通常为mern/server/server.js),请导入@apollo/server及其expressMiddleware。然后,实例化和启动Apollo Server:

import express from 'express';
import cors from 'cors';
import records from "./routes/record.js";
import gql from "graphql-tag";
import { ApolloServer } from '@apollo/server';
import { buildSubgraphSchema } from '@apollo/subgraph';
import { expressMiddleware } from '@apollo/server/express4';
import resolvers from "./resolvers.js";
import { readFileSync } from "fs";
const PORT = process.env.PORT || 5050;
const app = express();
app.use(cors());
app.use(express.json());
const typeDefs = gql(
readFileSync("schema.graphql", {
encoding: "utf-8",
})
);
const server = new ApolloServer({
schema: buildSubgraphSchema({ typeDefs, resolvers }),
});
// Note you must call `start()` on the `ApolloServer`
// instance before passing the instance to `expressMiddleware`
await server.start();
app.use("/record", records);
// start the Express server
app.listen(PORT, () => {
console.log(`Server is running on port: ${PORT}`);
});

接下来,您将使用中间件将之前定义的集成到一个路由中。

第5步:将/graphql路由添加到您的服务器API端点

在同一个服务器文件中,添加/graphql路由:

app.use("/record", records);
// Specify the path to mount the server
app.use(
'/graphql',
cors(),
express.json(),
expressMiddleware(server),
);
app.listen(PORT, () => {
console.log(`Server is running on port: ${PORT}`);
});

此路由提供了访问Apollo Server的预先生成的解析器函数。注意,/records路由尚未删除。这意味着你的Express服务器可以处理GraphQL和RESTful路由。

第6步:启动服务器

你现在可以启动服务器!从你的项目服务器目录中运行以下命令

npm start

你的控制台应该显示Server is running on port: 5050

第7步:执行你的第一个查询

你现在已经可以在服务器上执行GraphQL查询。要执行你的第一个查询,你可以使用Apollo Sandbox

在你的浏览器中访问你的MERN服务器,在/graphql路由,它将打开

Apollo Sandbox

沙箱UI包括

  • 一个URL输入栏,用于连接到其他(在上左角)
  • 用于模式探索、搜索和设置的选项卡(在左侧)
  • 一个用于编写和执行查询的 操作面板(位于中间)
  • 一个用于查看 查询结果的 响应面板(位于右侧)

要了解更多关于Sandbox提供的信息,请查看 Sandbox文档

服务器支持 记录,让我们开始吧!将此GraphQL 查询字符串粘贴到 操作面板中并点击运行按钮以执行 records 查询。

query GetRecords {
records {
name
position
level
}
}

你应该在 响应面板中看到你的记录。

完整示例

你可以在Code Sandbox上查看和复制完整的服务器示例。

Edit server-getting-started

下一步

恭喜你完成了教程! 🎉 在你的MERN应用程序中集成GraphQL服务器是朝着创建更高效、灵活和以用户为中心的Web体验迈出的重要一步。现在,你已经将Apollo Server集成到你的MERN堆栈应用程序中,你就可以使用 GraphOS 来构建和更快地扩展了。

虽然这个教程只涵盖了MERN堆栈的服务器部分,但 /client 中的 完整示例继续了教程的剩余内容,并实现了 @apollo/client 与服务器交互。有关实现Apollo Client的更多信息,请参阅 入门文档

为了更多地接触GraphQL和Apollo的服务器和客户端库,请查看我们的交互式 Odyssey教程

上一页
构建集成
下一页
构建和运行查询
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,简称Apollo GraphQL。

隐私政策

公司