欢迎光临
我们一直在努力

Prisma 生态中的 GraphQL Yoga 完全指南:基于 Express 与 Apollo Server 的轻量级 GraphQL 服务器

Prisma 生态中的 GraphQL Yoga 完全指南:基于 Express 与 Apollo Server 的轻量级 GraphQL 服务器

【免费下载链接】prisma1 💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated] 【免费下载链接】prisma1 项目地址: https://gitcode.com/gh_mirrors/pr/prisma1

GraphQL Yoga(graphql-yoga)是一个开箱即用的全功能 GraphQL 服务器,它以"极简配置、开箱即用"为核心设计目标,内置订阅(Subscriptions)、文件上传、GraphQL Playground、Apollo Tracing 等能力。在 Prisma 时代,它是官方推荐的 GraphQL 服务器层,几乎所有 Prisma 官方 Boilerplate(TypeScript、Node、React Fullstack)都以它作为入口服务器,连接由 Prisma 生成的数据库 CRUD API。读完本文,你将掌握 GraphQLServer 的完整配置项、server.start 的启动参数、订阅与上传的开启方式,以及如何将服务器部署到 Now 与 Heroku,并学会在需要时从默认 Express 配置中"eject"出更多自定义能力。

什么是 graphql-yoga

graphql-yoga 是一个全功能的 GraphQL 服务器,其设计重点在于易于配置、性能良好与优秀的开发者体验。它不是一个从零实现的 GraphQL 引擎,而是基于一系列成熟库的"组合封装",把搭建 GraphQL 服务器所需的样板代码全部抽象掉:

关注点底层依赖
Web 服务器框架 express / apollo-server
订阅(Subscriptions) graphql-subscriptions / subscriptions-transport-ws
GraphQL 引擎与 Schema 辅助 graphql.js / graphql-tools
交互式 IDE graphql-playground

这种"站在巨人肩膀上"的架构,使 graphql-yoga 具备了三个核心优势:

  • 最轻松的 GraphQL 服务器启动方式:提供合理的默认配置,包含启动服务器所需的一切,几乎零样板代码;
  • 内置订阅支持:基于 WebSocket 的 GraphQL Subscriptions 原生支持,无需额外接线;
  • 高度兼容:与所有 GraphQL 客户端(Apollo、Relay 等)配合良好,无缝融入你的 GraphQL 工作流。

在 Prisma 生态中的位置

在本仓库(Prisma 1.x 文档体系)中,graphql-yoga 是构建 GraphQL 服务器的标准组件。例如 TypeScript Quickstart 中,src/index.ts 是服务器的入口,通过 GraphQLServer 实例拉起整个应用,并在 context 中注入 Prisma 实例以连接数据库服务:

const server = new GraphQLServer({
typeDefs: './src/schema.graphql', // points to the application schema
resolvers,
context: req => ({
…req,
db: new Prisma({
endpoint: 'http://localhost:4466/my-app/dev', // the endpoint of the Prisma DB service
secret: 'mysecret123', // specified in `database/prisma.yml`
debug: true, // log all GraphQL queries & mutations
}),
}),
})

从源码结构看,Prisma 的 GraphQL 服务器由两层组成:graphql-yoga 提供 Web 服务器能力(HTTP 端点、订阅、Playground),prisma-binding 负责生成与 Prisma 数据库 API 之间的绑定。GraphQL Yoga 文档在仓库中的对应位置是 docs/1.0/06-GraphQL-Ecosystem/01-GraphQL-Yoga/01-Overview.md,与它并列的还有 prisma-binding、graphql-cli、graphql-import 等生态组件文档。

功能特性一览

graphql-yoga 提供的开箱即用能力包括:

  • 完全遵循 GraphQL 规范(GraphQL spec-compliant)
  • 文件上传(File upload)
  • GraphQL 订阅(GraphQL Subscriptions)
  • TypeScript 类型定义(TypeScript typings)
  • 内置 GraphQL Playground 交互式 IDE
  • 可通过 Express 中间件扩展(Extensible via Express middlewares)
  • Apollo Tracing 性能追踪
  • 同时接受 application/json 与 application/graphql 两种 Content-Type
  • 随处可部署:now、up、AWS Lambda、Heroku 等

安装

使用 yarn 或 npm 安装即可:

yarn add graphql-yoga

由于 graphql-yoga 构建于 express、apollo-server、graphql-tools 等之上,安装时会一并引入这些依赖,你无需手动配置它们。

基本使用

快速开始

最小的 graphql-yoga 服务器只需要三样东西:类型定义(typeDefs)、解析器(resolvers)和一次启动调用:

import { GraphQLServer } from 'graphql-yoga'
// … 或使用 require()
// const { GraphQLServer } = require('graphql-yoga')

const typeDefs = `
type Query {
hello(name: String): String!
}
`

const resolvers = {
Query: {
hello: (_, { name }) => `Hello ${name || 'World'}`,
},
}

const server = new GraphQLServer({ typeDefs, resolvers })
server.start(() => console.log('Server is running on localhost:4000'))

启动后,服务器默认监听 localhost:4000,同时在该地址暴露 GraphQL 端点与 Playground。

在 Prisma 生态中,更典型的工程化用法是:typeDefs 指向应用 Schema 文件(./src/schema.graphql),resolvers 调用注入在 context 中的 db(prisma-binding 实例)来读写数据库。见 Resolver Patterns 教程 中的实际解析器写法:

delete(parent, { id }, ctx, info) {
return ctx.db.mutation.deletePost(
{
where: { id }
},
info
);
}

API:GraphQLServer 构造器

constructor(props: Props): GraphQLServer

props 参数支持以下字段:

KeyTypeDefaultNote
typeDefs String null 以 SDL(Schema Definition Language)书写的 GraphQL 类型定义,或指向类型定义文件的路径(当未提供 schema 时必须提供 *)
resolvers Object null 为 typeDefs 中指定的字段提供解析器(当未提供 schema 时必须提供 *)
schema Object null 一个 GraphQLSchema 实例(当未提供 typeDefs 和 resolvers 时必须提供 *)
context Object or Function {} 自定义数据,会被传递到整个解析器链;可以传对象,也可以传签名如 (req: Request) => any 的函数

(*) 向构造器提供 Schema 信息有两条主要路径:

  • 提供 typeDefs 与 resolvers、省略 schema:此时 graphql-yoga 会调用 graphql-tools 中的 makeExecutableSchema 自动构建 GraphQLSchema 实例;
  • 直接提供 schema、省略 typeDefs 与 resolvers。
  • 创建服务器的示例:

    const typeDefs = `
    type Query {
    hello(name: String): String!
    }
    `

    const resolvers = {
    Query: {
    hello: (_, { name }) => `Hello ${name || 'World'}`,
    },
    }

    const server = new GraphQLServer({ typeDefs, resolvers })

    关于 context 的实战用法:在 Prisma Boilerplate 中,context 通常以函数形式提供,接收 Express 的 req,并把 req 与 db(Prisma 绑定)合并后传入解析器链——这既保证了请求级数据的传递(如当前登录用户),也让所有解析器都能访问数据库操作入口。完整的工程化组合可以参阅 React & Apollo Quickstart 中的 server/src/index.js。

    API:server.start(…)

    start(options: Options, callback: ((options: Options) => void) = (() => null)): Promise<void>

    GraphQLServer 实例化之后,调用 start 方法即可启动服务。它接收两个参数:

    • options:启动配置对象(字段见下表);
    • callback:在服务器启动前被调用的函数,可用于打印服务器已启动的信息。

    options 对象包含以下字段:

    KeyTypeDefaultNote
    cors Object null 传给 cors 中间件的配置选项(如 origin、credentials 等)
    tracing Boolean or String 'http-header' 控制是否启用 Apollo Tracing;若传字符串,可选值为 'enabled'、'disabled'、'http-header'
    port Number 4000 服务器监听端口(也可以通过设置 PORT 环境变量来指定)
    endpoint String '/' GraphQL 的 HTTP 端点路径
    subscriptions String or false '/' 订阅(WebSocket)端点路径;设为 false 则完全禁用订阅
    playground String or false '/' Playground 交互式 IDE 的端点路径;设为 false 则禁用 Playground
    uploads Object or false null 文件上传限制配置;对象可包含 maxFieldSize、maxFileSize、maxFiles 三个键(值均为 Number);设为 false 则禁用文件上传

    此外,options 还透传以下 apollo-server 选项:

    KeyTypeNote
    cacheControl Boolean 启用返回 Cache Control 数据的扩展
    formatError Number 在把错误发送给客户端前对每个错误进行处理的函数
    logFunction LogFunction 记录执行耗时等事件的日志函数
    rootValue any 传给 GraphQL 执行的 RootValue
    validationRules Array of functions 对客户端查询额外应用的 GraphQL 校验规则
    fieldResolver GraphQLFieldResolver 自定义的字段解析器(用于上传限制等场景的字段级处理)
    formatParams Function 批处理中每个查询在执行前格式化参数时调用的函数
    formatResponse Function 每个响应在执行后格式化时调用的函数
    debug boolean 执行出错时打印额外的调试日志

    完整示例——自定义端口、端点与订阅路径:

    const options = {
    port: 8000,
    endpoint: '/graphql',
    subscriptions: '/subscriptions',
    playground: '/playground',
    }

    server.start(options, ({ port }) => console.log(`Server started, listening on port ${port} for incoming requests.`))

    PubSub

    订阅功能的底层依赖 graphql-subscriptions 提供的 PubSub 机制。graphql-yoga 直接复用了该包的 PubSub 类,你可以在解析器中 publish 事件、在订阅解析器中 asyncIterator 订阅事件,具体 API 与 graphql-subscriptions 的原生文档一致,无需额外适配层。

    订阅与实时数据实战

    graphql-yoga 默认开启订阅端点(默认路径 '/',可与 HTTP 端点同址,也可以像上面那样单独配置为 /subscriptions)。一个典型的订阅场景是"计数器每隔 2 秒递增并触发一次订阅事件"。实现要点:

  • 在 typeDefs 中定义 Subscription 类型与对应事件;
  • 用 PubSub 实例发布事件;
  • 在订阅解析器中返回 pubsub.asyncIterator('事件名');
  • 通过 WebSocket 连接到 subscriptions 端点接收实时推送。
  • graphql-subscriptions 与 subscriptions-transport-ws 是订阅的底层支撑,graphql-yoga 已将二者的协议接线封装完毕,你只需要关注业务事件本身。

    开发工作流:Playground 即开即用

    服务器启动后,GraphQL Playground 开箱即用,通常运行在 localhost:4000。Playground 不仅是发送查询的 IDE,还自带自动生成的文档面板,展示该 API 支持的所有查询、变更与订阅操作。

    在 Prisma Boilerplate 中,Playground 还支持"双 API 并排"工作流(参见 TypeScript Quickstart 与 React & Apollo Quickstart):

    • app:Web 服务器的 GraphQL API,由应用 Schema(src/schema.graphql)定义,暴露给客户端应用;
    • database:Prisma 数据库服务的 CRUD GraphQL API,由Prisma Schema(src/generated/prisma.graphql)定义,由 datamodel.graphql 经 prisma deploy 生成。

    这种模式让你在开发期既能以"产品 API"的视角调试应用层查询,也能直接对数据库层执行完整的 CRUD 操作,例如直接创建一篇 isPublished: true 的文章:

    mutation {
    createPost(
    data: {
    title: "What I love most about GraphQL",
    text: "That it is declarative.",
    isPublished: true
    }
    ) {
    id
    }
    }

    部署

    使用 now 部署

    按照以下步骤将你的 graphql-yoga 服务器部署到 Zeit Now:

  • 下载 Now Desktop(内含 now CLI);
  • 在终端中进入 graphql-yoga 服务器的根目录;
  • 执行 now。
  • now 会上传你的源码并调用 package.json 中的 start 脚本来启动远端服务器。更详细的步骤可参考 Deployment with Now 教程,该教程还包含通过环境变量进行高级部署的说明。

    使用 Heroku 部署

    按照以下步骤部署到 Heroku:

  • 下载并安装 Heroku CLI(原 Heroku Toolbelt);
  • 执行 heroku login 登录 Heroku CLI;
  • 进入 graphql-yoga 服务器的根目录;
  • 执行 heroku create 创建 Heroku 实例;
  • 执行 git push heroku master 部署你的 GraphQL 服务器。
  • up 与 AWS Lambda

    up 与 AWS Lambda 的部署支持在文档撰写时处于"即将推出"(Coming soon)状态,使用前请以 graphql-yoga 最新发布版的能力为准。

    与手写 Express + GraphQL 服务器相比的 FAQ

    graphql-yoga 与 apollo-server 等工具相比如何?

    如前所述,graphql-yoga 构建于多种包之上:graphql.js、express、apollo-server 等,每个包都提供了构建 GraphQL 服务器所需的一部分功能。

    如果直接使用这些包,你需要自己完成大量组装工作并编写很多样板代码。graphql-yoga 抽象掉了初始的复杂性与样板代码,用一组合理的默认配置让你快速上手——可以把它理解为构建 GraphQL 服务器的 create-react-app。

    难道不能用 express 和 graphql.js 自己搭建服务器吗?

    graphql-yoga 的全部意义在于便捷性与优秀的"上手"体验:它把从零搭建 GraphQL 服务器的复杂度抽象掉,是一种务实的服务器引导方式,正如 create-react-app 消除了初学 React 时的摩擦。

    当 graphql-yoga 的默认配置对你来说过于"紧身"时,你可以随时eject(脱离),直接使用它底层的那套工具——不存在任何锁定或魔法阻止你这样做。

    如何从标准的 Express 配置中 eject?

    graphql-yoga 的核心价值在于你无需手写配置 Express 应用的样板代码。但一旦需要更定制化的行为(比如添加日志、错误上报等自定义中间件),默认配置可能就不再适合你。

    此时,GraphQLServer 通过其 express 属性直接暴露底层的 express.Application,你可以直接挂载任意中间件:

    server.express.use(myMiddleware())

    也可以把中间件精确绑定到 GraphQL 端点路由上:

    server.express.post(server.options.endpoint, myMiddleware())

    添加在该路由上的任何中间件,都会在 apollo-server-express 中间件之前执行——这为鉴权、限流、请求日志等横切关注点提供了干净的插入点。

    与 Prisma 生态的深度结合

    graphql-yoga 在本仓库中不是孤立组件,而是贯穿整个 Prisma 1.x 教程体系的基础设施:

    • 服务器搭建:TypeScript Quickstart 与 Node Quickstart 均以 GraphQLServer 作为入口,通过 context 注入 Prisma 绑定;
    • 解析器模式:Resolver Patterns 展示了如何在 graphql-yoga 解析器中通过 ctx.db 完成增删改查;
    • 权限控制:Permissions 教程 演示了如何利用 context 中的请求信息与 graphql-yoga 的中间件机制实现角色鉴权(如 ADMIN 角色);
    • 部署:Deployment with Now 完整覆盖了从 Boilerplate 到云端上线的流程。

    这种组合模式(graphql-yoga 负责服务器层 + prisma-binding 负责数据库绑定层)构成了 Prisma 1.x 时代"应用 Schema / 数据库 Schema 双 Schema"开发范式的基础,也是理解后续 Prisma 版本演进的重要起点。

    总结

    graphql-yoga 用极简的 API 封装了搭建生产级 GraphQL 服务器所需的全部要素:合理的默认配置、内置订阅与上传、可插拔的 Express 中间件、完善的启动选项,以及 Now/Heroku 等平台的零成本部署路径。在 Prisma 生态中,它是连接客户端应用与 Prisma 数据库服务的标准服务器层,配合 prisma-binding 与 Playground,构成了从数据模型到可交互 API 的完整闭环。当你需要更多定制能力时,"eject"到底层 express 与 apollo-server 的路径始终畅通,这让它既适合快速原型,也能平滑演进到复杂生产场景。

    【免费下载链接】prisma1 💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated] 【免费下载链接】prisma1 项目地址: https://gitcode.com/gh_mirrors/pr/prisma1

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:171主机测评 » Prisma 生态中的 GraphQL Yoga 完全指南:基于 Express 与 Apollo Server 的轻量级 GraphQL 服务器
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址