【问题标题】:"Single source of truth" schema/validation class for server (NestJs/GraphQL/TypeGraphQL/Prisma) and client (NextJs)服务器(NestJs/GraphQL/TypeGraphQL/Prisma)和客户端(NextJs)的“单一事实来源”模式/验证类
【发布时间】:2021-11-12 12:21:51
【问题描述】:

我在服务器上使用NX monorepoNestJs/GraphQL/TypeGraphQL(内置于@nestjs/graphql)/Prisma/PostgreSQL 和客户端上的NextJs 构建一个Typescript 应用程序.

使用此堆栈(对 GraphQL 使用代码优先方法时),您需要为每个实体(例如,“用户”)提供以下架构:

  1. Prisma 模型架构(用 Prisma 自己的 Prisma Schema 语言编写),用于对数据库进行建模:
model User {
  id Int @id @default(autoincrement())
  name String
  email String @unique
  password String
  createdAt DateTime @default(now()) @map("created_at")
  @@map("users")
}
  1. GraphQL 返回的实体架构(用于定义解析器返回的内容。装饰器来自 TypeGraphQL,但从 @nestjs/graphql 导入):
import { Field, ObjectType, ID } from '@nestjs/graphql';

@ObjectType()
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;

  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  createdAt: Date;
}
  1. GraphQL DTO 读取/输入架构(用于确定当有人查询您的 /graphql 端点时需要/验证哪些字段)。如您所见,我正在使用 'class-validator' 包来使用装饰器执行验证:
import { InputType, Field } from '@nestjs/graphql';
import { IsEmail, IsNotEmpty } from 'class-validator';

@InputType()
export class SignupInput {
  @Field()
  @IsNotEmpty()
  name: string;

  @Field()
  @IsNotEmpty()
  @IsEmail()
  email: string;

  @Field()
  @IsNotEmpty()
  password: string;
}
  1. 客户端 (NextJs) 表单输入验证架构。在客户端,我使用 React Hook Form,并使用“class-validator”包向它传递一个验证类:
class SignupForm {
  @IsNotEmpty({ message: 'Name is a required' })
  name: string;

  @IsNotEmpty({ message: 'Email is required' })
  @IsEmail({}, { message: 'This is not an email' })
  email: string;

  @IsNotEmpty({ message: 'Password is required' })
  password: string;
}

如您所见,这些不同的架构之间有很多重叠之处。本着保持代码 DRY 的精神,我希望找到一种在代码的所有不同部分之间共享单一模式的方法。

关于 Prisma,我认为这是一场失败的战斗,他们要求你用他们的 Prisma Schema Language 编写你的模型。 There is a package that makes working with TypeGraphQL easier,但它出现在not to be working with NestJs。如果有人知道有什么不同,请说!

关于 TypeGraphQL,他们的文档中确实有一个关于 how to use their schema in the browser 的部分,这意味着它可以与我的 NextJs 客户端共享。但是,经过数小时的尝试,我无法使其正常工作。主要是,我认为这要么是因为我使用了@nestjs/graphql 提供的 TypeGraphQL,要么是因为我的 NX monorepo 处理 Webpack 配置的方式。

一些有用的链接:

https://github.com/MichalLytek/type-graphql/issues/100

https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config

https://github.com/nrwl/nx/issues/3175

https://yonatankra.com/how-to-use-custom-webpack-configuration-in-a-nrwl-project/

任何帮助将不胜感激。

【问题讨论】:

    标签: graphql next.js nestjs monorepo typegraphql


    【解决方案1】:

    注意:我是 Remult 的作者之一

    使用Remult,您有一个 TypeScript 类(每个实体),它作为 API 端点、API 客户端和 ORM 的单一事实来源。它还可以在前端(例如,在发送突变请求之前)和后端运行实体装饰器中定义的 TypeScript 验证代码。

    唯一需要注意的是,虽然当前版本的 Remult 可用于公开 GraphQL 端点,但当前 API 客户端仅支持 RESTful。除此之外,我认为它可以很好地适合您的堆栈。

    【讨论】:

    • 谢谢诺姆,这看起来很有希望!祝项目顺利
    猜你喜欢
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2012-12-19
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多