在本系列中,您将学习如何使用 React、GraphQL、Prisma 以及其他一些将这三者联系在一起的实用工具来实现端到端类型安全。
目录
- 简介
- 设置 GraphQL Codegen
- 编写 GraphQL 查询
- 使用 GraphQL Codegen 生成类型
- 替换手动输入的类型
- 安装和设置 urql
- 查询您的数据
- 将您的项目推送到 Github
- 部署 API
- 部署 React 应用程序
- 总结与最终想法
简介
在本系列的最后一部分中,您将设置端到端类型安全拼图的最后一块:代码生成!这将使您的类型在 API 和前端客户端之间保持同步,并允许您安全地通过网络查询数据。最后,您将部署您的应用程序!
如果您错过了本系列的第一部分,这里简要概述一下您将在本应用程序中使用的技术以及一些先决条件。
您将使用的技术
以下是您将在本系列中使用的主要工具
- Prisma 作为对象关系映射器 (ORM)
- PostgreSQL 作为数据库
- Railway 用于托管您的数据库
- TypeScript 作为编程语言
- GraphQL Yoga 作为 GraphQL 服务器
- Pothos 作为代码优先的 GraphQL schema 构建器
- Vite 用于管理和搭建您的前端项目
- React 作为前端 JavaScript 库
- GraphQL Codegen 用于根据 GraphQL schema 为前端生成类型
- TailwindCSS 用于应用程序样式设计
- Render 用于部署您的 API 和 React 应用程序
假定知识
虽然本系列将尝试从初学者的角度详细介绍所有内容,但以下知识将有所帮助
- JavaScript 或 TypeScript 的基本知识
- GraphQL 的基本知识
- React 的基本知识
开发环境
为了跟随提供的示例进行操作,您需要具备
- Node.js 已安装。
- Prisma VSCode 扩展 已安装。 (可选)
设置 GraphQL Codegen
目前,Prisma 根据您的数据库 schema 生成一组 TypeScript 类型。Pothos 使用这些类型来帮助构建 GraphQL 类型定义。这两个部分的结果是一个 GraphQL schema
您的前端项目目前有一组手动定义的类型,这些类型是在本系列的第一部分中构建的。它们与 API 中的类型“兼容”,但并非直接相关
到目前为止,这工作正常。但是,如果 API 中引入、更新或删除了新字段会发生什么?您的前端应用程序将不知道 API 中发生了更改,并且两个项目中的类型定义将变得不同步。
如何确保您通过网络检索的 user
对象(例如)将包含您的 React 应用程序期望的所有字段?这就是 GraphQL Codegen 的用武之地
GraphQL Codegen 将根据您的 GraphQL schema 和您在前端应用程序中编写的查询,在您的 React 项目中生成 TypeScript 类型和查询助手。
因此,类型在您的应用程序中的整个流程将如下所示
- Prisma 将根据您的数据库 schema 生成类型。
- Pothos 将使用这些类型通过 API 公开 GraphQL 类型。
- GraphQL Codegen 将读取您的 GraphQL schema,并为您的前端代码库生成类型,表示可通过 API 获得的内容以及如何与之交互。
安装
要开始使用,请通过终端导航到您的 React 应用程序的代码库中
您将需要几个不同的软件包来设置 GraphQL Codegen。运行以下命令以安装所需的软件包
以下是每个软件包所需原因的简要概述
graphql
:允许您使用 GraphQL 的库。@graphql-codegen/cli
:CLI 工具,允许您使用不同的插件从 GraphQL API 生成资产。@graphql-codegen/typescript
:GraphQL Codegen 基于 TypeScript 的插件的基础插件。此插件获取您的 GraphQL API 的 schema,并为每个 GraphQL 类型生成 TypeScript 类型。@graphql-codegen/typescript-operations
:GraphQL Codegen 插件,根据您编写的查询生成表示查询和响应的 TypeScript 类型。@graphql-codegen/typed-document-node
:GraphQL Codegen 插件,生成您编写的任何查询的抽象语法树 (AST) 表示。
注意:不要太担心这些插件的细节。只需知道它们为 GraphQL schema 中的每个 GraphQL 对象、查询和 mutation 类型生成 TypeScript 类型,并帮助使您的 API 请求类型安全。
配置插件
现在这些插件已安装,并且您对它们的作用有了大致了解,是时候配置它们了。
在您的项目根目录中,创建一个名为 codegen.yml
的新文件。这将保存 GraphQL Codegen 的配置
此文件中将填写三个配置
schema
:您的 GraphQL schema 的 URLdocuments
:查找代码库中任何.graphql
文件的 blobgenerates
:告诉 GraphQL Codegen 要生成什么以及要使用哪些插件的配置
此配置文件让 GraphQL Codegen 知道 GraphQL schema 在 localhost:4000/graphql
可用,在哪里找到您的查询,以及在哪里使用您安装的所有插件输出生成的类型。
但是,为了实际生成类型,您需要设置一个脚本来运行生成命令。将以下脚本添加到 package.json
这为您提供了一种实际生成类型的方法!但是,您还没有完全准备好。
如果您没有任何查询,GraphQL Codegen 将无法为您的 GraphQL 查询生成任何类型!
编写 GraphQL 查询
为了保持组织性,您将在 graphql
文件夹中的单独文件中编写查询。继续在 src
目录中创建该文件夹
此应用程序只需要一个查询,它将检索用户列表及其消息。在 graphql
目录中创建一个名为 users.query.graphql
的新文件
您的应用程序只需要来自 API 的几条信息:每个用户的 name
和他们的消息 body
数据。
为该数据编写以下 GraphQL 查询
使用 GraphQL Codegen 生成类型
现在您有了一个可以使用的查询,您可以生成表示您的查询、响应以及可通过您的 API 获得的类型的类型!
运行您之前设置的 script
注意:在运行以下命令之前,请确保您的 GraphQL API 已启动并正在运行!您可以使用 API 目录中的
npm run dev
来启动服务器。
您应该看到类似于以下的输出
如在您的 codegen.yml
文件中配置的那样,您将在 src/graphql
中找到一个名为 generated.ts
的新文件。
此文件包含生成的类型。以下是每个插件生成的类型和对象
这些类型和对象是您的 GraphQL API 以及您编写的查询的精确表示,并且是将您的 API 和客户端连接起来的桥梁。
替换手动输入的类型
现在您有了从 API 本身生成的类型,您将用这些类型替换手动编写的类型。
转到 src/types.ts
。在该文件的顶部,从 src/graphql/generated.ts
导入 GetUsersQuery
类型
您导入此类型而不是完整的 User
和 Note
类型的原因是 GetUsersQuery
类型可以访问更特定的一组类型,这些类型仅包含您的查询检索的字段。
将该文件中的现有类型替换为以下内容,以公开表示您的查询结果的类型
如果您转到 src/components/UserDisplay.tsx
并检查用于 user
prop 的类型,您现在将看到它使用从您的 GraphQL 查询和 API 生成的类型
现在,您几乎已经将端到端类型安全拼图的每一块都放到了正确的位置。您的类型从数据库一直到前端应用程序都是同步的。
唯一缺少的是实际消化您的 API,而不是使用静态数据。您将希望以类型安全的方式执行此操作,以确保您仅查询 API 中存在的数据,并检索前端期望的所有字段。
GraphQL Codegen 已经生成了执行此操作所需的类型和查询对象。您只需要使用它们!
安装和设置 urql
要查询您的 GraphQL API,您将使用 urql,这是一个 GraphQL 客户端库,可让您轻松查询 GraphQL API 并与 React 集成。
您首先需要安装依赖项
此库为您提供两个您需要的导出:一个 Provider
组件和一个 createClient
函数。
您需要使用 Provider
和 createClient
函数将 urql 提供给您的应用程序。在 src/main.tsx
中,从 urql 库导入它们
接下来,使用 createClient
函数创建 urql 客户端的实例。客户端接收一个配置对象,其中包含一个 url
键,该键指向您的 GraphQL API 的 url。
在本地开发时,这应该是 https://127.0.0.1:4000/graphql
,但是一旦 API 部署,这将需要更改。使用环境变量允许您通过环境提供 API url,同时在开发中回退到 localhost URL
将 urql 提供给您的应用程序的最后一步是将您的 App
组件包装在 urql Provider
组件中,并将实例化的客户端传递给该组件
查询您的数据
您现在可以使用 urql 查询您的数据了!转到 src/App.tsx
并从 urql 导入 useQuery
函数。还要从 graphql/generated.ts
导入 GetUsersDocument
对象,因为这将包含您的查询的 AST 表示
在 App
函数中,您现在可以使用以下查询替换静态变量和数据
这使用 GetUserDocument
查询对象从您的 API 请求数据,并在正确类型的变量中返回它。
您不再需要 User
类型导入,因为类型已经在 GetUsersDocument
对象中指定。您还需要调整用于在 JSX 中映射每个用户的代码,因为查询结果现在在嵌套对象中返回。生成的文件应如下所示
请注意,您的 API 请求结果是根据 API 本身中的类型正确键入的!如果您的 API 和客户端都在运行,请转到浏览器。您现在应该看到您的所有数据!
恭喜!🎉 至此,您已经实现了一个完全端到端类型安全的应用程序,它由两个独立的部分组成:一个 API 和客户端。
剩下要做的唯一事情是部署项目,以便您可以共享它!
将您的项目推送到 Github
您将使用 Render 来部署您的两个代码库。但是,在此之前,您需要将您的代码托管在 Github 上。
注意:如果您还没有 Github 帐户,您可以在此处免费创建一个。
在主页的左上角,点击 New 按钮以创建新的存储库
为您的存储库命名,然后点击 Create repository
您将需要检索此存储库的 SSH url 以供稍后使用。从下面显示的位置获取它
现在在您的 React 应用程序中,运行以下命令以初始化和推送本地存储库,将 <url>
替换为 SSH url
接下来,您将为您的 API 代码库重复这些步骤。从您的 Github 仪表板创建另一个新存储库
为存储库命名,然后点击 Create repository
您应该再次看到一个包含一些设置说明的页面。从与之前相同的位置获取 SSH url
最后,通过终端导航到您的 GraphQL API 的代码库,并运行以下命令集。同样,将 <url>
替换为您的 SSH url
部署 API
现在您的代码在 Github 上可用,您可以部署您的代码库了!
转到 Render,如果您还没有帐户,请创建一个免费帐户。
您将部署的第一个内容是您的 GraphQL API。在您的仪表板上,点击 New Web Service 按钮,这将允许您部署 Node.js 应用程序
在此页面上,如果您尚未这样做,请点击 Github 标题下的 + Connect account,以授予 Render 访问权限以列出您的 Github 存储库
连接您的帐户后,您应该在 Connect a repository 标题下看到您的可用存储库。选择您的 GraphQL API 存储库。
系统将提示您输入一些不同的选项
- name:选择您喜欢的任何名称
- Environment:
Node
- Region:坚持默认
- Branch:
main
- Build Command:
npm run build
- Start Command:
npm run dev
在这些选项下方,选择 Free 计划
展开页面底部附近的 Advanced 部分。您将在此处定义一个环境变量,该变量将保存您的数据库 URL。
点击 Add Environment Variable 按钮,并添加一个名为 DATABASE_URL
的变量,其值是到您的 Postgres 数据库的连接字符串
最后,在页面底部,点击 Create Web Service 按钮
这将触发部署过程!部署完成后,您将能够访问 Render 提供的 URL 以查看您的 GraphQL API。
从下面显示的位置复制 URL,并在新的浏览器窗口中导航到 /graphql
路由
部署 React 应用程序
现在您的 API 已部署,您将部署您的 React 应用程序。
返回 Render 仪表板,然后点击页面顶部的 New 按钮。选择 Static Site 选项
将此静态站点连接到您的 React 应用程序的 Github 存储库。
系统将再次提示您填写一些详细信息以部署此应用程序
- name:选择您喜欢的任何名称
- Branch:
main
- Build Command:
npm run build
- Publish directory:
dist
在 Advanced 部分下,添加一个名为 VITE_API_URL
的环境变量,其值是您的已部署 GraphQL API 在 /graphql
路由上的 URL。例如
最后,点击页面底部的 Create Static Site 按钮以部署应用程序。
当部署完成后,转到页面顶部可用的 URL。如果一切顺利,您应该看到您的应用程序已上线!
总结与最终想法
在本文中,您完成了您的应用程序并部署了它!在此过程中,您
- 设置了 GraphQL Codegen,以使您的 TypeScript 类型在整个技术栈中保持同步
- 将您的两个代码库都发布到 Github
- 使用 Render 部署了您的两个应用程序
在本系列中,您逐步完成了使用 Prisma、GraphQL 和 React 作为主要技术构建完全类型安全的应用程序的每个步骤。您使用的所有工具的强大功能非常惊人,使您可以构建可扩展、安全的应用程序。
如果您对本系列中涵盖的任何内容有任何疑问,请随时在 Twitter 上与我联系。
不要错过下一篇文章!
注册 Prisma 新闻通讯