nestjs - Prisma 客户端类型系统与服务方法创建强耦合

标签 nestjs prisma

我正在使用 prisma ORM 和 nestjs,它非常棒。您能否帮助我了解如何将数据库层与服务方法分开,因为 prisma 客户端查询生成的结果是 prisma 客户端本身生成的类型(所以当我转向 typeorm 时我不会拥有这些类型)。我如何防止我的服务方法返回 prisma 客户端而不是我的自定义实体生成的类型结果的这种耦合。希望这是有道理的。

最佳答案

生成的@prisma/client库负责生成类型以及自定义实体类。因此,如果您更换 Prisma,您最终会失去两者。

这里有两种可能的解决方法,可以将服务方法的类型与 Prisma ORM 解耦。

解决方法 1:独立于 Prisma 生成类型

通过这种方法,您将来可以通过手动定义函数的类型来完全摆脱 Prisma。您可以使用 Prisma 生成的类型作为引用(或者直接复制粘贴它们)。让我给你举个例子。

想象这是您的 Prisma 架构。

model Post {
  id        Int      @default(autoincrement()) @id
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String   @db.VarChar(255)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}


model User {
  id      Int      @default(autoincrement()) @id
  name    String?
  posts   Post[]
}

您可以定义一个 getUserWithPosts 函数,如下所示:


// Copied over from '@prisma/client'. Modify as necessary.
type User = {
    id: number
    name: string | null     
}

// Copied over from '@prisma/client'. Modify as necessary.
type Post = {
    id: number
    createdAt: Date
    updatedAt: Date
    title: string
    authorId: number
}

type UserWithPosts = User & {posts: Post[]}

const prisma = new PrismaClient()

async function getUserWithPosts(userId: number) : Promise<UserWithPosts> {
    let user = await prisma.user.findUnique({
        where: {
            id: userId,
        },
        include: {
            posts: true
        }
    })
    return user;
}

这样,您应该能够完全摆脱 Prisma 并将其替换为您选择的 ORM。一个显着的缺点是,这种方法增加了 Prisma 架构更改时的维护负担,因为您需要手动维护类型。

解决方法 2:使用 Prisma 生成类型

您可以将 Prisma 保留在代码库中,以便生成 @prisma/client 并将其用于您的类型。这可以通过 @prisma/client 公开的 Prisma.validator 类型实现。用于演示完全相同功能的代码片段:


// 1: Define the validator
const userWithPosts = Prisma.validator<Prisma.UserArgs>()({
    include: { posts: true },
})

// 2: This type will include a user and all their posts
type UserWithPosts = Prisma.UserGetPayload<typeof userWithPosts>

// function is same as before
async function getUserWithPosts(userId: number): Promise<UserWithPosts>  {
    let user = await prisma.user.findUnique({
        where: {
            id: userId,
        },
        include: {
            posts: true
        }
    })
    return user;
}

此外,您始终可以使用 Introspect 将 Prisma 类型更新为当前数据库状态。特征。即使您使用其他 ORMS/查询生成器/SQL 进行的更改也适用。

如果您想了解更多详细信息,我在这里提到的很多内容都可以在 Operating against partial structures of your model types 中找到。 Prisma 文档中的概念指南。

最后,如果这不能解决您的问题,我会要求您打开 new issue问题和您的用例。这确实有助于我们跟踪人们面临的问题并确定优先顺序。

关于nestjs - Prisma 客户端类型系统与服务方法创建强耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68374582/

相关文章:

angular - 类型错误 : provideModuleMap is not a function ~ NestJS

node.js - 类验证器 @ValidateIf() 无法正常工作

typescript - 在 JestJS 中测试私有(private)方法

nestjs - 无法运行测试,因为 Nest 找不到模块

javascript - GraphQL 突变抛出错误

nestjs - SpyOn TypeORM 存储库更改单元测试 NestJS 的返回值

graphql - 错误: Valid values for the strategy argument of `@scalarList` are: RELATION

graphql - 在 Prisma/GraphQL 中实现搜索功能

javascript - Prisma 中的数据建模与关系