graphql:@apollo/server集成express

@apollo/server3与@apollo/server4采用了不同的方式: 3:express作为apolloserver的中间件 4:apolloserver提供了一个expressMiddleware的中间件,作为express的中间件运行 官网给了很详细的3-->4的说明[www.apollographql.com/docs/apollo...]

示例代码

javascript 复制代码
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 { typeDefs, resolvers } from "./schema";
const app = express();
///////
const httpServer = http.createServer(app);
//////
const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
/////应用expressMiddleware中间件:将graphql ApolloServer服务集成express
app.use(
  "/graphql",
  cors(),
  express.json(),
  expressMiddleware(server, {
    context: async ({ req }) => ({ token: req.headers.token }),
  })
);
await new Promise((resolve) => httpServer.listen({ port: 4000 }, resolve));
console.log(`🚀 Server ready at http://localhost:4000/graphql`);

在大多数情况下,直接使用const app = express();然后通过app.listen(...)启动Express应用程序已经足够用了。这种方式对于绝大多数基于Express的Web应用来说都是充分的,因为app.listen(...)在内部会创建一个HTTP服务器。

然而,使用http.createServer(app)并结合const app = express();有其特定的用途和优势,特别是当您需要更细粒度的控制或想要集成其他类型的HTTP服务时。

为什么使用http.createServer(app)

  1. 更高级的服务器设置

    • 创建一个显式的HTTP服务器对象可以让您对服务器进行更详细的配置和控制。例如,您可能需要配置HTTPS服务器或与WebSocket服务器共享相同的HTTP服务器实例。
  2. 与其他HTTP服务共享

    • 在某些情况下,您可能需要让Express应用和其他HTTP服务(如WebSocket服务)共享同一个HTTP服务器。这在实现实时通信功能时很常见。
  3. 统一管理

    • 创建一个单独的HTTP服务器实例可以让您在一个地方管理HTTP相关的所有设置,这可能会让代码组织得更清晰,特别是在复杂的应用中。

示例

使用单独的HTTP服务器实例可以在WebSocket服务器和Express应用之间共享同一个HTTP/S服务器:

ini 复制代码
javascriptCopy code
const express = require('express');
const http = require('http');
const WebSocket = require('ws');

const app = express();
const httpServer = http.createServer(app);

// 设置WebSocket服务器
const wss = new WebSocket.Server({ server: httpServer });

// Express路由
app.get('/', (req, res) => {
  res.send('Hello World');
});

// 启动服务器
httpServer.listen(3000, () => {
  console.log('Server is running on port 3000');
});

在这个例子中,Express应用和WebSocket服务都通过同一个httpServer实例运行,这意味着它们可以共享相同的端口和底层网络资源。

总结

虽然在许多简单应用中直接使用app.listen(...)就足够了,但在需要更高级配置或特定集成(如与WebSocket一起使用)的情况下,显式创建一个HTTP服务器实例并将Express应用作为中间件使用是一个更灵活的选择。

简化版示例

javascript 复制代码
import cors from "cors";
import express from "express";
import { authMiddleware, handleLogin } from "./auth.js";
import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
const PORT = 9000;
const app = express();
//照常做express的中间件控制
app.use(cors(), express.json(), authMiddleware);
//照常设置express 路由
app.post("/login", handleLogin);
// 添加一个ApolloServer 并启动
const apolloServer = new ApolloServer();
await apolloServer.start();
//应用expressMiddleware -->将apollo server集成进express server
app.use("/graphql", expressMiddleware(apolloServer));
//启动express服务
app.listen({ port: PORT }, () => {
  console.log(`Server running on port ${PORT}`);
});

选择"/graphql"这个路由来应用中间件,其实是一个非官方的标准或约定;

  • 区分不同的服务 :如果您的应用同时提供GraphQL和RESTful服务,使用/graphql可以明确区分这两种服务的路由,减少混淆。
  • 中间件分离 :在Express等框架中,您可以通过定义不同的路由来分别管理不同的中间件。这意味着所有发送到/graphql的请求都将专门由GraphQL中间件处理。

代码

test

相关推荐
忙碌54410 天前
区块链应用开发的完整实战指南:从理论到落地的企业级解决方案
架构·区块链·restful·graphql
yuki_uix19 天前
GraphQL 重塑:从 API 语言到 AI 时代的"逻辑神经系统"
前端·graphql
果粒蹬i21 天前
【HarmonyOS】RN of HarmonyOS实战开发项目+Apollo GraphQL客户端
华为·harmonyos·graphql
程序猿阿伟22 天前
《GraphQL批处理与全局缓存共享的底层逻辑》
后端·缓存·graphql
程序猿阿伟23 天前
《GraphQL状态图建模与低时延控制能力解析》
后端·graphql
程序猿阿伟23 天前
《面向第三方的GraphQL开放平台设计指南》
后端·graphql
程序猿阿伟23 天前
《GraphQL 强类型架构下的错误处理体系设计指南》
后端·架构·graphql
爬山算法1 个月前
Hibernate(78)如何在GraphQL服务中使用Hibernate?
java·hibernate·graphql
Irene19911 个月前
HTTP 请求方法选择与 RESTful 实践(对比 GraphQL、RPC)
rpc·restful·http请求·grpc·graphql
Dontla1 个月前
GraphQL介绍(声明式查询)文件上传GraphQL文件上传
后端·graphql