【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载本篇是 HowToGraphQL 仓库中 TypeScript Apollo 后端教程的第一章Getting Started。你将在一台已安装 Node.js 的机器上从mkdir开始逐步搭建一个 GraphQL 服务的完整骨架配置 TypeScript 编译环境、用 Nexus 以 code-first 方式生成 GraphQL Schema、用 Apollo Server 3 创建 Web 服务器并在 Apollo Studio Explorer 中跑通人生第一个 GraphQL 查询。读完本章你将掌握一套可直接复制的项目初始化 → Schema 生成 → 服务启动 → 查询验证的完整流程并理解 GraphQL Schema、根类型与类型修饰符的核心理论。本章对应的教程栈在仓库中被定义为一个独立的后端教程条目见 src/data/stacks.ts其目标是用 TypeScript、Apollo Server、Nexus 与 Prisma 构建你自己的 GraphQL 服务器本仓库中该教程的完整章节内容位于 content/backend/typescript-apollo/上一章 0-introduction.md 已对技术选型做了整体介绍。前置条件检查 Node.js 版本整个教程假设你已经具备基本的 JavaScript/TypeScript 与 Web 开发知识并使用 npm 作为包管理器详细的假设清单见 0-introduction.md 的 Prerequisites 一节。动手之前请先确认本机 Node.js 版本满足要求——本教程要求Node.jsv12或以上。在终端中运行以下命令查看当前版本node --version如果版本过低可以通过官方安装包或版本管理器例如nvm升级 Node.js。版本达标后即可进入下一步。创建项目并初始化 package.json本教程会手把手带你从零构建 GraphQL 服务器因此第一步是创建存放服务端代码的目录并完成 npm 初始化。打开终端进入你选定的工作位置依次执行mkdir hackernews-typescript cd hackernews-typescript npm init -y这三条命令分别完成创建名为hackernews-typescript的新目录、切换进该目录、以默认配置初始化出一个package.json。package.json是 Node.js 应用的配置文件它记录了应用的全部依赖项以及scripts等其它配置信息。后续安装的所有依赖和自定义脚本都会写进这个文件。注教程中的代码块通常会附带形如(path.../hackernews-typescript/)的目录标注用来提示你应当在哪个目录下执行该终端命令跟随标注操作即可。安装与配置 TypeScript既然这是一条 TypeScript 教程首先需要安装typescript编译器。同时还要安装ts-node-dev——它能在开发时即时转译 TS 文件并在代码变更后自动重启 API 服务这对开发体验至关重要。此外还需要一份tsconfig.json来声明 TypeScript 编译选项。在项目目录中安装这两个开发依赖并创建空的tsconfig.jsonnpm install --save-dev typescript^4.3.5 ts-node-dev^1.1.8 touch tsconfig.json安装完成后把以下配置写入tsconfig.json{ compilerOptions: { target: ES2018, module: commonjs, lib: [ esnext ], strict: true, rootDir: ., outDir: dist, sourceMap: true, esModuleInterop: true } }各选项的作用如下target: ES2018指定编译输出的 JavaScript 目标版本为 ES2018决定可使用哪些较新的语言特性module: commonjs指定模块系统为 CommonJS这是 Node.js 环境下的标准选择lib: [esnext]声明编译时可用的标准库类型定义即内置 API 的类型使用esnext可以解锁最新的语言内置能力strict: true开启一组覆盖广泛、更严格的类型检查行为使程序获得更强的类型安全。但严格模式有时会把一些实际无害的类型写法也报成错误如果遇到你确信不是 bug 的类型报错可以临时将该项改为false或用// ts-ignore注释屏蔽特定行rootDir: .指定源文件根目录用于推导输出目录的层级结构outDir: dist指定编译产物输出到dist目录sourceMap: true为编译产物生成 source map方便调试时定位回原始 TS 源码esModuleInterop: true允许默认导入与 CommonJS 模块互操作让import x from y这类写法兼容更广泛。安装 GraphQL 服务端依赖在编写任何代码之前还需要安装三个运行时依赖nexus负责生成 GraphQL Schemagraphql提供 GraphQL 语言与执行引擎apollo-server则负责创建带 GraphQL 能力的 HTTP Web 服务器。执行npm install apollo-server^3.1.1 graphql^15.5.1 nexus^1.1.0版本说明教程所有安装命令都使用^前缀如^3.1.1这表示 npm 会保持主版本号不变、自动更新到最新的 minor/patch 版本。根据语义化版本semver约定破坏性变更只应发生在主版本升级中因此这种写法能确保教程中的代码不会因依赖意外升级而失效。这是本教程系列统一的依赖安装约定。各依赖的定位与特性如下apollo-server是一个功能完备的 GraphQL 服务器基于 Express.js 等库构建用于打造生产级 GraphQL 服务。它具备这些亮点完全符合 GraphQL 规范开箱即用地支持两种 GraphQL 客户端界面Apollo Explorer 与 GraphQL Playground可配置为与 Express 服务器配合使用内置查询性能追踪query performance tracing可部署到多种环境Vercel、标准虚拟机、AWS Lambda、Heroku 等。Nexus是一个采用 code-first代码优先方式创建类型安全 GraphQL Schema 的库——你通过编写标准的 JavaScript/TypeScript 代码来声明 Schema 长什么样因此被称为code-first。它的特性包括富有表现力、声明式的 Schema 构建 API免费获得完整类型安全自动生成 GraphQL SDLschema.graphql文件与现有 GraphQL 框架和中间件开箱即用如apollo-server、graphql-middleware等。关于 code-first 与 schema-first 的区别以及定义类型 → 生成 SDL → 实现 resolver的完整工作流会在下一章 2-a-simple-query.md 中详细展开。搭建项目布局src/schema.ts 与 src/index.ts目录和依赖就绪后接下来建立服务器骨架。起步阶段只需要两个文件schema.ts用 Nexus 生成 Schemaindex.ts用 Apollo 创建 GraphQL Web 服务器。创建src目录并生成这两个 TypeScript 文件mkdir src touch src/schema.ts src/index.ts用 Nexus 生成第一个 Schema现在开始写第一批代码。打开src/schema.ts输入以下内容import { makeSchema } from nexus import { join } from path export const schema makeSchema({ types: [], // 1 outputs: { schema: join(process.cwd(), schema.graphql), // 2 typegen: join(process.cwd(), nexus-typegen.ts), // 3 }, })逐条理解代码中的编号注释// 1你的 GraphQL Schema 将由许多类型组成这些类型将以数组形式传给types选项。目前刻意保持为空数组// 2Nexus 为你生成的第一个输出文件是扩展名为.graphql的 Schema 文件即 GraphQLSchema Definition LanguageSDL用来声明 API 的结构。本章稍后会专门讲解 SDL// 3第二个输出文件是名为typegen的 TypeScript 文件里面包含 GraphQL Schema 中所有类型对应的 TypeScript 类型定义。这些自动生成的类型能保证应用代码的类型安全并让 GraphQL Schema 的定义与实现始终同步。运行这段代码看看会发生什么npx ts-node --transpile-only src/schema--transpile-only让ts-node跳过完整类型检查、只做转译适合快速生成文件。执行后项目根目录下会出现两个由 Nexus 生成的新文件schema.graphql和nexus-typegen.ts。打开schema.graphql你会看到一个名为Query的类型其中只有一个ok字段type Query { ok: Boolean! }这是 Nexus 在未收到任何类型信息时创建的默认 Schema。而nexus-typegen.ts中则包含大量自动生成的 TypeScriptinterface与type定义。你通常不需要深究这些内容因为它们会自动注入到 Nexus 函数的签名中但在某些时刻你也可以从该文件中查阅某个类型并手动用于自己的代码。在进入下一节之前先把两个 npm 脚本写入package.json便于随时快速重新生成 Schema、以及启动开发服务器scripts: { test: echo \Error: no test specified\ exit 1, dev: ts-node-dev --transpile-only --no-notify --exit-child src/index.ts, generate: ts-node --transpile-only src/schema.ts },这两个脚本的用途npm run generate当 Nexus 代码发生任何变化时重新生成schema.graphql与nexus-typegen.tsnpm run dev启动 Web 服务器并监听文件变化自动重启。其中dev脚本使用ts-node-dev的--transpile-only跳过类型检查加快启动、--no-notify关闭系统通知与--exit-child子进程退出时一并退出等参数。创建并启动 GraphQL 服务器Schema 已经有了接下来在index.ts中创建 GraphQL 服务器。输入以下代码import { ApolloServer } from apollo-server; // 1 import { schema } from ./schema; export const server new ApolloServer({ schema, }); const port 3000; // 2 server.listen({port}).then(({ url }) { console.log( Server ready at ${url}); });代码解读// 1你通过 Nexus 创建的schema对象定义了 GraphQL Schema。实例化 ApolloServer 时必须传入它因为 Apollo Server 正是依据该 Schema 来决定 GraphQL API 支持哪些操作// 2启动服务器并指定端口。服务器启动完成后会在 Promise 中返回一个url字符串。现在启动服务器npm run dev如果一切顺利终端会出现如下输出 Server ready at http://localhost:3000/用浏览器访问http://localhost:3000/即可看到 Apollo Server 的欢迎页面。点击页面上的Query your server按钮会跳转到 Apollo Studio Explorer——一个在线的、基于 Web 的 GraphQL IDE可以运行查询、浏览 Schema还附带许多高级功能。在左侧的Schema标签页Apollo logo 下第一个图标里可以看到整个 GraphQL Schema。目前内容还很少但后续章节中它会成为浏览 Schema 细节的得力工具。现在来运行ok查询。回到Explorer标签页在Operations操作窗口中输入以下查询并点击Query按钮query Query { ok }你会得到这样的响应{ data: { ok: true } }恭喜你已成功实现并验证了自己的第一个 GraphQL 查询开发技巧试着在代码的任意位置做一处小改动你会发现日志输出中会出现Restarting: ...字样并自动重启服务器——这是因为ts-node-dev会持续监测代码变化并让服务器即时同步。从本章起请始终保持ts-node-dev运行这样服务器始终在线同时 Nexus 也能持续生成最新的 GraphQL SDL 与类型定义。GraphQL Schema 理论基础跑通第一个查询之后是时候理解一下 Schema 背后的原理了。每一个 GraphQL API 的核心都是它的 GraphQL Schema。本章只讲基础部分想更深入理解 Schema 在 GraphQL API 中的角色可继续阅读本教程后续章节。SDL 与根类型GraphQL Schema 使用Schema Definition LanguageSDL定义。SDL 拥有一套类型系统可以像 Java、TypeScript、Swift、Go 等强类型语言一样定义数据结构。每个 GraphQL Schema 都有三个特殊的根类型root typesQuery、Mutation和Subscription。它们分别对应 GraphQL 的三种操作类型查询、变更与订阅。根类型上的字段被称为根字段root fields它们定义了该 API 可用的操作。以刚才的简单 Schema 为例type Query { ok: Boolean! }这个 Schema 只有一个名为ok的根字段。发送给 GraphQL API 的查询、变更或订阅总是必须以根字段开头这里的根字段只有一个所以该 API 能接受的查询也就只有这一种。ok的类型被标注为Boolean!意味着它只可能返回true或false末尾的!表示该字段是**非空non-nullable**的——如果尝试在这个字段上返回null服务器会直接报错。标量类型与对象类型再看一个稍复杂的例子type Query { users: [User!]! user(id: ID!): User } type Mutation { createUser(name: String!): User! } type User { id: ID! name: String! }这里共有三个根字段Query上的users与user以及Mutation上的createUser。由于根字段的返回类型引用了User必须额外定义User类型否则 Schema 定义将不完整。从这个 Schema 可以推导出哪些 API 操作我们知道每个操作都以根字段开头但这里根字段的类型本身是对象类型[User!]!、User、User!而不是之前ok那种标量类型。标量类型scalar types是 GraphQL Schema 中最基础的类型本身没有子字段类似编程语言中的原始类型。GraphQL 内置 5 种默认标量Int、Float、String、Boolean和ID。你也可以根据应用需求定义或引入自定义标量——这会在本教程后续章节中讲到。当根字段的类型是对象类型时你可以在查询中进一步展开该对象类型的字段被展开的部分称为选择集selection set。类型修饰符列表与非空看上面的示例 Schema三个根字段对User类型使用了不同的类型修饰符列表和/或非空的组合含义各不相同users的返回类型[User!]!返回一个本身不能为null的列表且列表中的元素也不能为null。因此你拿到的要么是空列表要么是只包含非空User对象的列表user(id: ID!)的返回类型User返回值可能是null也可能是User对象createUser(name: String!)的返回类型User!该操作总是返回一个User对象。实现上述 Schema 的 GraphQL API 可以接受如下操作# 查询所有用户 query { users { id name } } # 按 id 查询单个用户 query { user(id: user-1) { id name } } # 创建一个新用户 mutation { createUser(name: Bob) { id name } }需要注意几点上述示例总是查询返回的User对象的id和name。两者都可以省略但查询对象类型时选择集中至少需要查询它的一个字段选择集中的字段写法不受根字段类型是必填还是列表影响——选择集始终按对象类型的字段展开书写。关于查询执行过程——GraphQL 服务器如何按 Schema 逐层调用 resolver 并组装响应——可以进一步阅读本仓库的 content/graphql/advanced/1-server.md 章节基础语法SDL 定义、查询/变更/订阅写法则在 content/graphql/basics/2-core-concepts.md 中有系统讲解。理论到此为止接下来进入实操环节的收尾部分。可选用 GraphQL Playground 替代 Apollo Studio本教程使用的 Apollo Server 3 默认内置 Apollo Studio。但如果你没有网络连接或更偏好一款离线 IDE可以改用 GraphQL Playground。如果你能正常使用 Apollo Studio则无需执行本节操作——对大多数跟随本教程学习的人而言Apollo Studio 是最方便的选择。对index.ts做如下修改以启用 GraphQL Playgroundimport { ApolloServer } from apollo-server; import { ApolloServerPluginLandingPageGraphQLPlayground } from apollo-server-core; import { schema } from ./schema; export const server new ApolloServer({ schema, plugins: [ApolloServerPluginLandingPageGraphQLPlayground()], }); const port 3000; server.listen({port}).then(({ url }) { console.log( Server ready at ${url}); });通过向ApolloServer的plugins数组注入来自apollo-server-core的ApolloServerPluginLandingPageGraphQLPlayground插件访问http://localhost:3000/时就会加载 GraphQL Playground 界面。另外你也可以随时使用任意其它 GraphQL 客户端工具来测试你的服务器例如 Insomnia、Postman 或 Altair。本章自检回顾本章内容回答下面这个问题这也是本仓库中该章节配套的随堂测验题根字段root fields在 GraphQL API 中扮演什么角色A. 三个根字段分别是 Query、Mutation 和 SubscriptionB. 根字段实现implement了可用的 API 操作C. 根字段定义了define可用的 API 操作D. 根字段是选择集的另一种叫法正确答案是C正如SDL 与根类型一节所述根类型上的字段定义了该 API 可用的操作而具体如何实现返回数据则是由后文将讲到的 resolver 函数负责的。选项 A 混淆了根类型与根字段选项 B 混淆了定义与实现。下一步至此你已拥有一个能启动、能响应查询的最小 GraphQL 服务器骨架。在下一章 2-a-simple-query.md 中你将按照用 Nexus 定义类型 → 重新生成 SDL 与类型 → 实现 resolver的 code-first 工作流为 Hacker News 克隆实现第一个真实业务操作——feed查询并深入理解查询的解析resolution过程与琐碎 resolver的自动推断机制。如果你想了解本仓库中这条教程的完整脉络与配套元数据可以查看 content/backend/typescript-apollo/0-introduction.md技术选型与教程目标、src/data/stacks.ts教程条目的站点元数据定义以及 meta/writing-guidelines.md本仓库教程的写作与章节组织规范。赞分享【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载相关推荐GoExec WMI模块详解3分钟学会远程进程创建与输出捕获技巧GoExec WMI模块详解3分钟学会远程进程创建与输出捕获技巧 GoExec是一款强大的Windows远程执行多工具其WMIWindows ManageHowToGraphQL 之 TypeScript Apollo Server 全栈 GraphQL 服务实战总结从零搭建到生产部署HowToGraphQL 之 TypeScript Apollo Server 全栈 GraphQL 服务实战总结从零搭建到生产部署 本篇是 HowToGHowToGraphQL Angular Apollo 入门实战从零搭建 Graphcool 后端与 Apollo Client 前端配置HowToGraphQL Angular Apollo 入门实战从零搭建 Graphcool 后端与 Apollo Client 前端配置 本文基于 Ho上一篇docker-stacks中的PySpark与Kafka流处理实时数据管道下一篇终极指南如何构建基于PySC2的星际争霸II脑机接口AI系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考