使用 Next.js , Nexus, Prisma 构建全栈项目
此教程翻译自《Complete Intruduction to Fullstack,Type-Safe GraphQL(feat.Next.js,Nexus,Prisma)》
我们将要从模板中构建全栈项目,会使用 Next.js ,Nexus,Prisma ,来实现 React 的后端渲染,GraphQL 接口。
技术栈浅析
首先,我们浅析一下我们选择的技术栈。
TypeScript - 前后端使用统一的编程语言
React 和 Next.js - 前端开发框架 React ,以及React 的服务端渲染库
Urql GraphQL client - GraphQL 的客户端
PostgreSQL - 数据库
Nexus - 一个 code-first 的 GraphQL 服务端
Prisma Client 和 Prisma Migrate - 用于数据库 ORM 操作的工具库(注意:Prisma Migrate 仍然在实验阶段)
现在,我们开始吧!
配置开发环境
在我们开始编写代码前,首先要配置开发环境所需要的软件,以便我们能够使用轻松的方式编写代码。我们使用的软件编辑器是 VS Code , 它的插件库里提供了 Prisma 和 GraphQL 的代码高亮和自动格式化工具,我们先在 VS Code 中安装下面两个插件。
截屏2020-08-30 上午10.02.16.png接下来,我们要安装 [docker](https://www.docker.com/get-started) (我们的 PostgreSQL 数据库将在 docker 容器中运行,当然其他的云数据库或本地安装的数据库亦可),具体安装教程请前往 [docker 官网](https://www.docker.com/get-started)。
注意事项
我们的开发工具是 mac pro 笔记本电脑,在 window 系统下的 pc 电脑运行结果如有不同,请先自行查找原因,然后在评论区留言讨论。
在命令行下运行指令,如无特别说明,一律是在项目根目录下运行。
新建一个 Next.js 项目
我们可以使用 ceate-next-app
工具包新建一个 Next.js 项目。在命令行工具输入下面的指令:
create-next-app
会使用 Git
自动下载项目初始化代码,并自动安装所有的依赖。指令运行完成以后,在 VS Code 打开项目目录,可以看到下图所示的项目结构。
<a name="yeBUt"></a>
安装 Nexus 和 Prisma
现在,我们安装 Nexus 框架和 nexus-plugin-prisma
包。在命令行工具中运行下面的指令:
Nexus 包含了提供 Typescript 语言类型编译支持的插件 Nexus TypeScript Language Service Plugin
,我们只需要在 Typescript 配置文件 tsconfig.json
中配置即可,修改代码如下:
使用 Docker 启动数据库
我们使用 docker-compose
保存 postgresql 容器的设置,在项目根目录下添加 docker-compose-yml
文件,文件内容如下:
其中 ${POSTGRESPWD}
是保存在 .env
文件中的数据库密码变量。同样的,在根目录下新建 .env
文件,并添加下面的代码:
然后在命令行中输入如下指令:
启动过程没有报错,即成功,命令会自动退出。 -d
时表示docker 容器在后台运行。
Prisma 连接数据库
我们要使用 Prisma 连接到上一步启动的 postgresql 数据库容器。首先,我们在根目录下新建 prisma
文件夹,然后在其中添加 .env
文件,然后在 .env
文件中添加环境变量 DATABASE_URL
,代码如下“
别忘了替换数据库的密码
因为 .env
文件里包含了密码这样的敏感信息,不应该提交到 git 仓库中,所以在 .gitignore
中添加省略 .env
。
最后,我们需要在 /prisma
创建 schema 文件,用于设置数据库配置,和数据库 model 描述。具体代码如下:
使用 Prisma 初始化数据库表结构
在 schema.prisma
写入的 model 描述就是数据库表的描述。我们接下来就要使用 @prisma/cli
工具在 数据库中自动创建,更新数据表。
在命令行工具中输入下面的指令:
运行结果如下图:
此时,Prisma 已经在 prisma
目录下创建了连接文件 migration
。截屏2020-08-30 下午3.37.04.png
最后,将连接的信息推送到数据中使用下面的指令:
运行完成以后,可以在数据库中看到我们在 prisma.schema
定义的 Hello
。<br />
我们使用的数据库 UI 工具是 TablePlus。
连接 Nexus 和 Next.js
Next.js 的 API routes 功能非常方便,我们只需要添加 /pages/api/graphql.ts
文件,然后启动 next.js 服务,就可以在 http://app-domain/api/graphql
访问 GraphqQL 服务。<br />在 graphql.ts
文件中编写下面的代码:
下面,我们在根目录创建 graphql
目录,并且在这个目录下新建 schema.ts
文件。在 schema.ts
文件中,我们首先初始化 nexus-plugin-prisma
插件,设置 CRUD 功能,并通过 plugin 和 nexus 连接。具体代码如下:
最后,在命令行中启动 nexus 服务
<a name="Kq7dR"></a>
此时,graphql 已经启动,访问 localhost:4000/graphql
可以看到 GraphQL Playground 已经运行(目前只有空的 schema)。<br />
编写 GrahphQL API
现在,我们开始写一个 API。
<a name="EpFFM"></a>
定义对象类型
首先,我们在 graphql/shema.ts
中定义一个 User
对象类型,这里使用的 nexus 定义对象的语法:
当你在 VS Code 中编写上面代码时,VS Code 将会自动完成这些字段( id
, name
)。这是因为我们已经在 prisma/schema.prisma
中定义好了 User
model。<br />现在,打开 Grapqhl Playground 并切换到 Schema 标签页。你会看到已经添加了 Grqphql 对象类型 User
。<br />
定义 Query 类型
Nexus 使用 schema.queryType
函数来定义 root Query
。<br />我们写一个查询全部 User
的 query
- allUsers
。<br />具体代码如下:
在 resolve
函数中,可以添加实际的逻辑代码。Prisma 客户端里可以操作 数据的实例 db
包含在上下文对象 ctx
中。 更多关于 Prisma 客户端 API 的信息可以在官网文档中了解。<br />Nexus-Prisma plugin 也包含了从数据库读取数据的方法,下面的代码可以直接定义读取 user
users
的 query。
别忘了,查询单个 user 时传入参数的 Input
类型描述也会自动生成。
<a name="Evowg"></a>
定义 Mutation 类型
举一反三,和 Query type 类似, Mutation
类型使用 schema.mutationType
类定义。<br />接下来,让我们来创建一个 bigRedButton
mutation 用来删除所有的 user 数据。代码如下:
同样的,nexus-prisma plutin 也为 mutation 提供了很多 CURD 函数。
自动生成的 GraphQL schema 如下:
现在,我们完整的 GraphqlQL API 已经完成了!接下来,我们尝试在 React 中使用 GraphQL 发送请求进行增删改查。
在 React 中使用 GraphQL
我们将会在前端代码中使用 Urql 。当然,也可以使用其他你熟悉的 GrphQL 客户端,比如 Apollo client 等。
设置 Urql GraphQL 客户端
首先,在命令行工具运行下面的安装指令:
然后,在 /pages
目录下新增 _app.tsx
文件。这个文件是特殊的 Next.js 组件,它会在初始化每一个页面时都会被执行。<br />我们在 /pages/_app.tsx
文件中添加下面的代码:
现在,在前端所有页面都可以使用 GrphQL 客户端来发送网络请求了!
使用 GraphQL client 查询所有用户
首先,在根目录下创建 components
文件夹,用来保存所有的组件文件。在 components
文件夹下创建 AllUsers.tsx
。 AllUsers.tsx
文件里定义 React 函数组件,组件内部将会请求 allUsers
GraphQL query 并把查询返回的结果显示出来。<br />我们现在 AllUser.tsx
中定义 gql 查询语句,如下代码:
接下来,定义查询请求返回后的数据类型,我们知道返回数据是一个包好所有 User
对象的数组。所以,我们定义如下类型:
最后,我们完成 React 函数组件,并发送请求获取所有的 User
数据。
完整版的函数组件代码如下:
最后,我们在 /pages/index.tsx
主页文件中渲染 AllUsers 组件,代码如下:
🥳 接下来,我们在命令行启动 next.js App ~
最后,访问 localhost:3000
。<br />
<a name="b3dVY"></a>
自动生成 `useQuery` hooks 和 types
如果我们想要自动生成 GraphQL API 的类型描述而不是手动定义所有的,我们可以使用一个非常酷的工具 GraphQL Code Generator ,它可以从 Nexus GraphQL 入口 schema 描述中直接生成客户端所需的类型定义代码。这样,我们就只需在 schema.prisma
文件定义一次类型,然后,客户端所使用的类型都会自动通过 GraphQL Code Generator
自动生成。<br />首先,在命令行工具运行下面的代码来安装所需的包:
然后,我们在根目录下添加 codegen.yml
配置文件来告诉 GraphQL Code Generator
的 GraphQL schema 访问地址等信息,我们项目的配置信息如下:
然后,我们需要在 graphql
目录下新建 queries.graphql.ts
文件,并将 components/AllUsers.tsx
中的 gql 标签对象剪切到 queries.graphql.ts
中。具体代码如下图:
最后,别忘了启动 nexus ,之后我们就可以在命令行运行如下指令,来自动生成类型定义了:
<br />如果希望开发过程中监听文件改变,自动生成类型定义的话,可以添加 --watch
参数。<br />指令运行成功以后,我们可以在产出目录 generated
中查看 graphql.tsx
文件内容,部分代码如下:
最后,我们在 components/AllUsers.tsx
中使用生成 useAllUsersQuery
函数来发送请求获取用户数据。代码如下:
<a name="MiabK"></a>
结尾
我们希望你能喜欢这篇实践教程,并学习到如何配置 prisma,nexus,nextjs 来完成全栈的开发!<br />你可以访问此 Github repo 下的 prisma-next-nexus
目录来查看完整代码。<br />
版权声明: 本文为 InfoQ 作者【夏木】的原创文章。
原文链接:【http://xie.infoq.cn/article/952139b5faf5d8510018ca576】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论