Skip to main content

从旧到新的 Nexus

概述

¥Overview

信息

本指南并非完全最新,因为它当前使用 nexus-plugin-prismadeprecated 版本。虽然这仍然有效,但建议今后使用新的 nexus-prisma 库或替代的代码优先 GraphQL 库(例如 绿萝)。如果你有任何疑问,请随时在我们的 Discord 上分享。

¥This guide is not fully up-to-date as it currently uses the deprecated version of the nexus-plugin-prisma. While this is still functional, it is recommended to use the new nexus-prisma library or an alternative code-first GraphQL library like Pothos going forward. If you have any questions, feel free to share them on our Discord.

本升级指南介绍如何升级基于 Prisma 1 并使用 nexus(< v0.12.0)或 @nexus/schemanexus-prisma(< v4.0.0)一起实现 GraphQL 服务器的项目。

¥This upgrade guide describes how to upgrade a project that's based on Prisma 1 and uses nexus (< v0.12.0) or @nexus/schema together with nexus-prisma (< v4.0.0) to implement a GraphQL server.

代码将升级到最新版本 @nexus/schema。此外,nexus-prisma 封装将被新的 nexus-plugin-prisma 取代。

¥The code will be upgraded to the latest version of @nexus/schema. Further, the nexus-prisma package will be replaced with the new nexus-plugin-prisma.

本指南假定你已经完成了 Prisma ORM 层升级指南。这意味着你已经:

¥The guide assumes that you already went through the guide for upgrading the Prisma ORM layer. This means you already:

  • 安装 Prisma ORM 2 CLI

    ¥installed the Prisma ORM 2 CLI

  • 创建了你的 Prisma ORM 2 架构

    ¥created your Prisma ORM 2 schema

  • 检查你的数据库并解决潜在的 模式不兼容

    ¥introspected your database and resolved potential schema incompatibilities

  • 安装并生成 Prisma 客户端

    ¥installed and generated Prisma Client

该指南进一步假设你有一个与此类似的文件设置:

¥The guide further assumes that you have a file setup that looks similar to this:

.
├── README.md
├── package.json
├── prisma
│ └── schema.prisma
├── prisma1
│ ├── datamodel.prisma
│ └── prisma.yml
└── src
├── generated
│ ├── nexus-prisma
│ ├── nexus.ts
│ ├── prisma-client
│ └── schema.graphql
├── types.ts
└── index.ts

重要的部分是:

¥The important parts are:

  • 使用 Prisma ORM 2 架构以 prisma 调用的文件夹

    ¥A folder called with prisma with your Prisma ORM 2 schema

  • 名为 src 的文件夹,其中包含你的应用代码

    ¥A folder called src with your application code

如果这不是你的项目结构,你需要调整指南中的说明以匹配你自己的设置。

¥If this is not what your project structure looks like, you'll need to adjust the instructions in the guide to match your own setup.

1. 升级 Nexus 依赖

¥ Upgrade Nexus dependencies

首先,你可以删除旧的 Nexus 和 Prisma 1 依赖:

¥To get started, you can remove the old Nexus and Prisma 1 dependencies:

npm uninstall nexus nexus-prisma prisma-client-lib prisma1

然后,你可以在项目中安装最新的 @nexus/schema 依赖:

¥Then, you can install the latest @nexus/schema dependency in your project:

npm install @nexus/schema

接下来,安装 Nexus 的 Prisma ORM 插件,这将允许你在 GraphQL API 中公开 Prisma ORM 模型(这是前 nexus-prisma 包的新版本):

¥Next, install the Prisma ORM plugin for Nexus which will allow you to expose Prisma ORM models in your GraphQL API (this is the new equivalent of the former nexus-prisma package):

npm install nexus-plugin-prisma

nexus-plugin-prisma 依赖打包了所有必需的 Prisma ORM 依赖。因此,你应该删除在升级应用的 Prisma ORM 层时添加安装的依赖:

¥The nexus-plugin-prisma dependency bundles all required Prisma ORM dependencies. You should therefore remove the dependencies that you added installed when you upgraded the Prisma ORM layer of your app:

npm uninstall @prisma/cli @prisma/client

但请注意,你仍然可以使用熟悉的命令调用 Prisma ORM 2 CLI:

¥Note however that you can still invoke the Prisma ORM 2 CLI with the familiar command:

npx prisma -v

注意:如果你在运行 npx prisma -v 时看到 Prisma 1 CLI 的输出,请务必删除 node_modules 文件夹并重新运行 npm install

¥Note: If you see the output of the Prisma 1 CLI when running npx prisma -v, be sure to delete your node_modules folder and re-run npm install.

2. 更新 Nexus 和 Prisma ORM 的配置

¥ Update the configuration of Nexus and Prisma ORM

首先,你可以删除新设置中不再需要的旧导入:

¥To get started, you can remove the old imports that are not needed any more with your new setup:

import { makePrismaSchema, prismaObjectType } from 'nexus-prisma'
import datamodelInfo from './generated/nexus-prisma'
import { prisma } from './generated/prisma-client'

相反,你现在将以下内容导入到你的应用中:

¥Instead, you now import the following into your application:

import { nexusSchemaPrisma } from 'nexus-plugin-prisma/schema'
import { objectType, makeSchema, queryType, mutationType } from '@nexus/schema'
import { PrismaClient } from '@prisma/client'

接下来,你需要调整当前创建 GraphQLSchema 的代码,这很可能是通过代码中的 makePrismaSchema 函数当前发生的。由于此函数是从已删除的 nexus-prisma 包中导入的,因此你需要将其替换为 @nexus/schema 包中的 makeSchema 函数。Nexus 的 Prisma ORM 插件的使用方式在最新版本中也发生了变化。

¥Next you need to adjust the code where you currently create your GraphQLSchema, most likely this is currently happening via the makePrismaSchema function in your code. Since this function was imported from the removed nexus-prisma package, you'll need to replace it with the makeSchema function from the @nexus/schema package. The way how the Prisma ORM plugin for Nexus is used also changes in the latest version.

以下是此类配置的示例:

¥Here's an example for such a configuration:

./src/index.ts
 const schema = makePrismaSchema({
const schema = makeSchema({

// Provide all the GraphQL types we've implemented
types: [Query, Mutation, UserUniqueInput, User, Post, Category, Profile],

// Configure the interface to Prisma
prisma: {
datamodelInfo,
client: prisma,
},
plugins: [nexusSchemaPrisma({
experimentalCRUD: true,
})],

// Specify where Nexus should put the generated files
outputs: {
schema: path.join(__dirname, './generated/schema.graphql'),
typegen: path.join(__dirname, './generated/nexus.ts'),
},

// Configure nullability of input arguments: All arguments are non-nullable by default
nonNullDefaults: {
input: false,
output: false,
},

// Configure automatic type resolution for the TS representations of the associated types
typegenAutoConfig: {
sources: [
{
source: path.join(__dirname, './types.ts'),
alias: 'types',
},
],
contextType: 'types.Context',
},
})

如果你之前输入了通过解析器链传递的 GraphQL context 对象,则需要像这样调整类型:

¥If you previously typed the GraphQL context object that's passed through your resolver chain, you need to adjust the type like so:

./src/types.ts
import { Prisma } from './generated/prisma-client'
import { PrismaClient } from '@prisma/client'

export interface Context {
prisma: Prisma
prisma: PrismaClient
}

3. 迁移你的 GraphQL 类型

¥ Migrate your GraphQL types

以下是使用最新版本 @nexus/schemanexus-plugin-prisma 创建 GraphQL 类型的两种方法之间的主要区别的快速概述。

¥Here's a quick overview of the main differences between the two approaches of creating GraphQL types with the latest versions of @nexus/schema and nexus-plugin-prisma.

  • prismaObjectType 功能不再可用,所有类型均使用 Nexus 的 objectType 功能创建。

    ¥The prismaObjectType function is not available any more, all types are created with Nexus' objectType function.

  • 要通过 Nexus 公开 Prisma 模型,你可以使用 t.model 属性,该属性添加到传递到 Nexus 的 definition 函数的 t 参数中。t.model 使你可以访问 Prisma 模型的属性并公开它们。

    ¥To expose Prisma models via Nexus, you can use the t.model property which is added to the t argument that's passed into Nexus' definition functions. t.model gives you access to the properties of a Prisma model and lets you expose them.

  • 通过 Nexus 公开 Prisma 模型的 CRUD 操作遵循类似的方法。这些通过 queryTypemutationType 类型的 definition 函数中的 t.crud 公开。

    ¥Exposing CRUD operations for Prisma models via Nexus follows a similar approach. These are exposed via t.crud in the definition functions of your queryType and mutationType types.

3.1.迁移 Post 类型

¥3.1. Migrating the Post type

与之前的 nexus-prisma 包的类型定义

¥Type definition with the previous nexus-prisma package

在示例应用中,User 类型定义如下:

¥In the sample app, the User type is defined as follows:

const User = prismaObjectType({
name: 'User',
definition(t) {
t.prismaFields([
'id',
'name',
'email',
'jsonData',
'role'
{
name: 'posts',
args: [], // remove the arguments from the `posts` field of the `User` type in the Prisma schema
},
])
},
})

最新版本的 @nexus/schemanexus-plugin-prisma 的类型定义

¥Type definition with the latest version of @nexus/schema and the nexus-plugin-prisma

使用最新版本的 @nexus/schema,你现在可以在主 schema 实例上访问 objectType 函数并公开 Prisma 模型中的所有字段,如下所示:

¥With the latest version of @nexus/schema, you can now access the objectType function on your main schema instance and expose all fields from the Prisma model like so:

const User = objectType({
name: 'User',
definition(t) {
t.model.id()
t.model.name()
t.model.email()
t.model.jsonData()
t.model.role()
t.model.posts({
pagination: false,
ordering: false,
filtering: false,
})
t.model.profile()
},
})

请注意,t.model 查看作为参数传递给 objectType 函数的对象中的 name 属性,并将其与 Prisma 架构中的模型进行匹配。在本例中,它与 User 模型相匹配。因此,t.model 公开了以 User 模型的字段命名的函数。

¥Note that t.model looks at the name attribute in the object that's passed as an argument to the objectType function and matches it against the models in your Prisma schema. In this case, it's matched against the User model. Therefore, t.model exposes functions that are named after the fields of the User model.

此时,你可能会在关系字段 postsprofile 上看到错误,例如:

¥At this point, you might see errors on the relation fields posts and profile, e.g.:

//delete-next-line
Missing type Post, did you forget to import a type to the root query?

这是因为你尚未将 PostProfile 类型添加到 GraphQL 架构中,一旦这些类型也成为 GraphQL 架构的一部分,错误就会消失!

¥This is because you didn't add the Post and Profile types to the GraphQL schema yet, the errors will go away once these types are part of the GraphQL schema as well!

3.2.迁移 Post 类型

¥3.2. Migrating the Post type

与之前的 nexus-prisma 包的类型定义

¥Type definition with the previous nexus-prisma package

在示例应用中,Post 类型定义如下:

¥In the sample app, the Post type is defined as follows:

const Post = prismaObjectType({
name: 'Post',
definition(t) {
t.prismaFields(['*'])
},
})

prismaFields 中的星号表示所有 Prisma 字段均已暴露。

¥The asterisk in prismaFields means that all Prisma fields are exposed.

最新版本的 @nexus/schemanexus-plugin-prisma 的类型定义

¥Type definition with the latest version of @nexus/schema and the nexus-plugin-prisma

使用最新版本的 @nexus/schema,你需要显式公开所有字段,无法选择仅公开 Prisma 模型中的所有内容。

¥With the latest version of @nexus/schema, you need to expose all fields explicitly, there's no option to just expose everything from a Prisma model.

因此,Post 的新定义必须明确列出其所有字段:

¥Therefore, the new definition of Post must explicitly list all its fields:

const Post = objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.title()
t.model.content()
t.model.published()
t.model.author()
t.model.categories()
},
})

请注意,t.model 查看 name 属性并将其与 Prisma 架构中的模型进行匹配。在本例中,它与 Post 模型相匹配。因此,t.model 公开了以 Post 模型的字段命名的函数。

¥Note that t.model looks at the name attribute and matches it against the models in your Prisma schema. In this case, it's matched against the Post model. Therefore, t.model exposes functions that are named after the fields of the Post model.

3.3.迁移 Profile 类型

¥3.3. Migrating the Profile type

与之前的 nexus-prisma 包的类型定义

¥Type definition with the previous nexus-prisma package

在示例应用中,Profile 类型定义如下:

¥In the sample app, the Profile type is defined as follows:

const Profile = prismaObjectType({
name: 'Profile',
definition(t) {
t.prismaFields(['*'])
},
})

prismaFields 中的星号表示所有 Prisma 字段均已暴露。

¥The asterisk in prismaFields means that all Prisma fields are exposed.

最新版本的 @nexus/schemanexus-plugin-prisma 的类型定义

¥Type definition with the latest version of @nexus/schema and the nexus-plugin-prisma

使用最新版本的 @nexus/schema,你需要显式公开所有字段,无法选择仅公开 Prisma 模型中的所有内容。

¥With the latest version of @nexus/schema, you need to expose all fields explicitly, there's no option to just expose everything from a Prisma model.

因此,Profile 的新定义必须明确列出其所有字段:

¥Therefore, the new definition of Profile must explicitly list all its fields:

const Profile = objectType({
name: 'Profile',
definition(t) {
t.model.id()
t.model.bio()
t.model.user()
t.model.userId()
},
})

请注意,t.model 查看 name 属性并将其与 Prisma 架构中的模型进行匹配。在本例中,它与 Profile 模型相匹配。因此,t.model 公开了以 Profile 模型的字段命名的函数。

¥Note that t.model looks at the name attribute and matches it against the models in your Prisma schema. In this case, it's matched against the Profile model. Therefore, t.model exposes functions that are named after the fields of the Profile model.

3.4.迁移 Category 类型

¥3.4. Migrating the Category type

与之前的 nexus-prisma 包的类型定义

¥Type definition with the previous nexus-prisma package

在示例应用中,Category 类型定义如下:

¥In the sample app, the Category type is defined as follows:

const Category = prismaObjectType({
name: 'Category',
definition(t) {
t.prismaFields(['*'])
},
})

prismaFields 中的星号表示所有 Prisma ORM 字段都已公开。

¥The asterisk in prismaFields means that all Prisma ORM fields are exposed.

最新版本的 @nexus/schemanexus-plugin-prisma 的类型定义

¥Type definition with the latest version of @nexus/schema and the nexus-plugin-prisma

使用最新版本的 @nexus/schema,你需要显式公开所有字段,无法选择仅公开 Prisma 模型中的所有内容。

¥With the latest version of @nexus/schema, you need to expose all fields explicitly, there's no option to just expose everything from a Prisma model.

因此,Category 的新定义必须明确列出其所有字段:

¥Therefore, the new definition of Category must explicitly list all its fields:

const Category = objectType({
name: 'Category',
definition(t) {
t.model.id()
t.model.name()
t.model.posts({
pagination: true,
ordering: true,
filtering: true,
})
},
})

请注意,t.model 查看 name 属性并将其与 Prisma 架构中的模型进行匹配。在本例中,它与 Category 模型相匹配。因此,t.model 公开了以 Category 模型的字段命名的函数。

¥Note that t.model looks at the name attribute and matches it against the models in your Prisma schema. In this case, it's matched against the Category model. Therefore, t.model exposes functions that are named after the fields of the Category model.

4. 迁移 GraphQL 操作

¥ Migrate GraphQL operations

下一步,你可以开始将所有 GraphQL 查询和突变从 "previous" GraphQL API 迁移到新 API。

¥As a next step, you can start migrating all the GraphQL queries and mutations from the "previous" GraphQL API to the new one.

对于本指南,将使用以下示例 GraphQL 操作:

¥For this guide, the following sample GraphQL operations will be used:

input UserUniqueInput {
id: String
email: String
}

type Query {
posts(searchString: String): [Post!]!
user(userUniqueInput: UserUniqueInput!): User
users(where: UserWhereInput, orderBy: Enumerable<UserOrderByInput>, skip: Int, after: String, before: String, first: Int, last: Int): [User]!
}

type Mutation {
createUser(data: UserCreateInput!): User!
createDraft(title: String!, content: String, authorId: ID!): Post
updateBio(userUniqueInput: UserUniqueInput!, bio: String!): User
addPostToCategories(postId: String!, categoryIds: [String!]!): Post
}

4.1.迁移 GraphQL 查询

¥4.1. Migrate GraphQL queries

在本部分中,你将把所有 GraphQL 查询从以前版本的 nexusnexus-prisma 迁移到最新版本的 @nexus/schemanexus-plugin-prisma

¥In this section, you'll migrate all GraphQL queries from the previous version of nexus and nexus-prisma to the latest version of @nexus/schema and the nexus-plugin-prisma.

4.1.1.迁移 users 查询

¥4.1.1. Migrate the users query

在我们的示例 API 中,示例 GraphQL 架构中的 users 查询的实现如下。

¥In our sample API, the users query from the sample GraphQL schema is implemented as follows.

const Query = prismaObjectType({
name: 'Query',
definition(t) {
t.prismaFields(['users'])
},
})

要在新的 Nexus 上获得相同的行为,你需要在 t.crud 上调用 users 函数:

¥To get the same behavior with the new Nexus, you need to call the users function on t.crud:

schema.queryType({
definition(t) {
t.crud.users({
filtering: true,
ordering: true,
pagination: true,
})
},
})

回想一下,crud 属性是由 nexus-plugin-prisma 添加到 t 的(使用与 t.model 相同的机制)。

¥Recall that the crud property is added to t by the nexus-plugin-prisma (using the same mechanism as for t.model).

4.1.2.迁移 posts(searchString: String): [Post!]! 查询

¥4.1.2. Migrate the posts(searchString: String): [Post!]! query

在示例 API 中,posts 查询的实现如下:

¥In the sample API, the posts query is implemented as follows:

queryType({
definition(t) {
t.list.field('posts', {
type: 'Post',
args: {
searchString: stringArg({ nullable: true }),
},
resolve: (parent, { searchString }, context) => {
return context.prisma.posts({
where: {
OR: [
{ title_contains: searchString },
{ content_contains: searchString },
],
},
})
},
})
},
})

此查询唯一需要更新的是对 Prisma ORM 的调用,因为新的 Prisma 客户端 API 看起来与 Prisma 1 中使用的 API 有点不同。

¥The only thing that needs to be updated for this query is the call to Prisma ORM since the new Prisma Client API looks a bit different from the one used in Prisma 1.

queryType({
definition(t) {
t.list.field('posts', {
type: 'Post',
args: {
searchString: stringArg({ nullable: true }),
},
resolve: (parent, { searchString }, context) => {
return context.prisma.post.findMany({
where: {
OR: [
{ title: { contains: searchString } },
{ content: { contains: searchString } },
],
},
})
},
})
},
})

请注意,db 对象由 nexus-plugin-prisma 自动附加到 context。它代表 PrismaClient 的一个实例,使你能够将查询发送到解析器内的数据库。

¥Notice that the db object is automatically attached to the context by the nexus-plugin-prisma. It represents an instance of your PrismaClient which enables you to send queries to your database inside your resolvers.

4.1.3.迁移 user(uniqueInput: UserUniqueInput): User 查询

¥4.1.3. Migrate the user(uniqueInput: UserUniqueInput): User query

在示例 API 中,user 查询的实现如下:

¥In the sample API, the user query is implemented as follows:

inputObjectType({
name: 'UserUniqueInput',
definition(t) {
t.string('id')
t.string('email')
},
})

queryType({
definition(t) {
t.field('user', {
type: 'User',
args: {
userUniqueInput: schema.arg({
type: 'UserUniqueInput',
nullable: false,
}),
},
resolve: (_, args, context) => {
return context.prisma.user({
id: args.userUniqueInput?.id,
email: args.userUniqueInput?.email,
})
},
})
},
})

你现在需要调整对 prisma 实例的调用,因为新的 Prisma 客户端 API 看起来与 Prisma 1 中使用的 API 有点不同。

¥You now need to adjust the call to your prisma instance since the new Prisma Client API looks a bit different from the one used in Prisma 1.

const Query = queryType({
definition(t) {
t.field('user', {
type: 'User',
args: {
userUniqueInput: arg({
type: 'UserUniqueInput',
nullable: false,
}),
},
resolve: (_, args, context) => {
return context.prisma.user.findUnique({
where: {
id: args.userUniqueInput?.id,
email: args.userUniqueInput?.email,
},
})
},
})
},
})

4.2.迁移 GraphQL 突变

¥4.2. Migrate GraphQL mutations

在本部分中,你会将 GraphQL 突变从示例架构迁移到最新版本的 @nexus/schemanexus-plugin-prisma

¥In this section, you'll migrate the GraphQL mutations from the sample schema to the latest versions of @nexus/schema and the nexus-plugin-prisma.

4.2.1.迁移 createUser 突变

¥4.2.1. Migrate the createUser mutation

在我们的示例 API 中,示例 GraphQL 模式的 createUser 突变实现如下。

¥In our sample API, the createUser mutation from the sample GraphQL schema is implemented as follows.

const Mutation = prismaObjectType({
name: 'Mutation',
definition(t) {
t.prismaFields(['createUser'])
},
})

要在最新版本的 @nexus/schemanexus-plugin-prisma 中获得相同的行为,你需要在 t.crud 上调用 createOneUser 函数并传递 alias,以便将 GraphQL 模式中的字段重命名为 createUser(否则,在所使用的函数之后,它将被称为 createOneUser):

¥To get the same behavior with the latest versions of @nexus/schema and the nexus-plugin-prisma, you need to call the createOneUser function on t.crud and pass an alias in order to rename the field in your GraphQL schema to createUser (otherwise it would be called createOneUser, after the function that's used):

const Query = queryType({
definition(t) {
t.crud.createOneUser({
alias: 'createUser',
})
},
})

回想一下,crud 属性是由 nexus-plugin-prisma 添加到 t 的(使用与 t.model 相同的机制)。

¥Recall that the crud property is added to t by the nexus-plugin-prisma (using the same mechanism as for t.model).

4.2.2.迁移 createDraft(title: String!, content: String, authorId: String!): Post! 查询

¥4.2.2. Migrate the createDraft(title: String!, content: String, authorId: String!): Post! query

在示例应用中,createDraft 突变的实现如下。

¥In the sample app, the createDraft mutation implemented as follows.

mutationType({
definition(t) {
t.field('createDraft', {
type: 'Post',
args: {
title: stringArg({ nullable: false }),
content: stringArg(),
authorId: stringArg({ nullable: false }),
},
resolve: (_, args, context) => {
return context.prisma.createPost({
title: args.title,
content: args.content,
author: {
connect: { id: args.authorId },
},
})
},
})
},
})

你现在需要调整对 prisma 实例的调用,因为新的 Prisma 客户端 API 看起来与 Prisma 1 中使用的 API 有点不同。

¥You now need to adjust the call to your prisma instance since the new Prisma Client API looks a bit different from the one used in Prisma 1.

const Mutation = mutationType({
definition(t) {
t.field('createDraft', {
type: 'Post',
args: {
title: stringArg({ nullable: false }),
content: stringArg(),
authorId: stringArg({ nullable: false }),
},
resolve: (_, args, context) => {
return context.prisma.post.create({
data: {
title: args.title,
content: args.content,
author: {
connect: { id: args.authorId },
},
},
})
},
})
},
})

4.2.3.迁移 updateBio(bio: String, userUniqueInput: UserUniqueInput!): User 突变

¥4.2.3. Migrate the updateBio(bio: String, userUniqueInput: UserUniqueInput!): User mutation

在示例 API 中,updateBio 突变的定义和实现如下。

¥In the sample API, the updateBio mutation is defined and implemented as follows.

mutationType({
definition(t) {
t.field('updateBio', {
type: 'User',
args: {
userUniqueInput: arg({
type: 'UserUniqueInput',
nullable: false,
}),
bio: stringArg(),
},
resolve: (_, args, context) => {
return context.prisma.updateUser({
where: {
id: args.userUniqueInput?.id,
email: args.userUniqueInput?.email,
},
data: {
profile: {
create: { bio: args.bio },
},
},
})
},
})
},
})

你现在需要调整对 prisma 实例的调用,因为新的 Prisma 客户端 API 看起来与 Prisma 1 中使用的 API 有点不同。

¥You now need to adjust the call to your prisma instance since the new Prisma Client API looks a bit different from the one used in Prisma 1.

const Mutation = mutationType({
definition(t) {
t.field('updateBio', {
type: 'User',
args: {
userUniqueInput: arg({
type: 'UserUniqueInput',
nullable: false,
}),
bio: stringArg(),
},
resolve: (_, args, context) => {
return context.prisma.user.update({
where: {
id: args.userUniqueInput?.id,
email: args.userUniqueInput?.email,
},
data: {
profile: {
create: { bio: args.bio },
},
},
})
},
})
},
})

4.2.4.迁移 addPostToCategories(postId: String!, categoryIds: [String!]!): Post 突变

¥4.2.4. Migrate the addPostToCategories(postId: String!, categoryIds: [String!]!): Post mutation

在示例 API 中,addPostToCategories 突变的定义和实现如下。

¥In the sample API, the addPostToCategories mutation is defined and implemented as follows.

mutationType({
definition(t) {
t.field('addPostToCategories', {
type: 'Post',
args: {
postId: stringArg({ nullable: false }),
categoryIds: stringArg({
list: true,
nullable: false,
}),
},
resolve: (_, args, context) => {
const ids = args.categoryIds.map((id) => ({ id }))
return context.prisma.updatePost({
where: {
id: args.postId,
},
data: {
categories: { connect: ids },
},
})
},
})
},
})

你现在需要调整对 prisma 实例的调用,因为新的 Prisma 客户端 API 看起来与 Prisma 1 中使用的 API 有点不同。

¥You now need to adjust the call to your prisma instance since the new Prisma Client API looks a bit different from the one used in Prisma 1.

const Mutation = mutationType({
definition(t) {
t.field('addPostToCategories', {
type: 'Post',
args: {
postId: stringArg({ nullable: false }),
categoryIds: stringArg({
list: true,
nullable: false,
}),
},
resolve: (_, args, context) => {
const ids = args.categoryIds.map((id) => ({ id }))
return context.prisma.post.update({
where: {
id: args.postId,
},
data: {
categories: { connect: ids },
},
})
},
})
},
})

5. 打扫干净

¥ Cleaning up

5.1.清理 npm 依赖

¥5.1. Clean up npm dependencies

如果你还没有卸载,你现在可以卸载与 Prisma 1 设置相关的依赖:

¥If you haven't already, you can now uninstall dependencies that were related to the Prisma 1 setup:

npm uninstall prisma1 prisma-client-lib

5.2.删除未使用的文件

¥5.2. Delete unused files

接下来,删除 Prisma 1 设置的文件:

¥Next, delete the files of your Prisma 1 setup:

rm -rf src/generated
rm -rf prisma1

5.3.停止 Prisma ORM 服务器

¥5.3. Stop the Prisma ORM server

最后,你可以停止运行 Prisma ORM 服务器。

¥Finally, you can stop running your Prisma ORM server.