NestJS + GraphQL + Prisma, CRUD敏捷开发!

为什么用 NestJS?

Nest是构建高效,可扩展的 Node.js Web 应用程序的框架。 它使用现代的 JavaScript 或 TypeScript(保留与纯 JavaScript 的兼容性),并结合 OOP(面向对象编程),FP(函数式编程)和FRP(函数响应式编程)的元素。

换句话说,开发后端为什么要用 NodeJS?当你看到这里的时候请看「为什么用 GraphQL」

为什么用 GraphQL?

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

请求你所要的数据,不多不少

向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少。 GraphQL 查询总是返回可预测的结果。使用 GraphQL 的应用可以工作得又快又稳,因为控制数据的是应用,而不是服务器。

获取多个资源,只用一个请求

GraphQL 查询不仅能够获得资源的属性,还能沿着资源间引用进一步查询。典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 可以通过一次请求就获取你应用所需的所有数据。这样一来,即使是比较慢的移动网络连接下,使用 GraphQL 的应用也能表现得足够迅速。

描述所有的可能,类型系统

GraphQL API 基于类型和字段的方式进行组织,而非入口端点。你可以通过一个单一入口端点得到你所有的数据能力。GraphQL 使用类型来保证应用只请求可能的数据,还提供了清晰的辅助性错误信息。应用可以使用类型,而避免编写手动解析代码。

所以?

目前,构建 GraphQL 的生态中,没有一个能和 Node 生态所产出的包能比拟的。

  • PHP 语言的 GraphQL 包老是不维护,GraphQL 标准更新后添加缓慢
  • Java 受语言特性影响,本身构建 GraphQL 就很繁琐。
  • Go 可用拓展包非常少
  • Dart 和 Go 一样,可用构建的包非常少

为什么选择 Prisma?

Prisma 官方说:“下一代的 Node.js 和 TypeScript ORM”,其实就是提供 CRUD 接口,所以 Prisma 和 GraphQL 的构建非常配。只需要实现 Prisma 提供的模板接口即可完成 GraphQL API 的构建

Prisma + GraphQL 弊端

这是我前半年时间非常痛苦的事情,Prisma 的 js client 只提供了 TypeScript 的 interface,用来做 IDE 的参数提示。所以可每次我编写 GraphQL types 的时候都需要实现一遍 Prisma 的 model interface 和 input interface。

解决方案

最近一直在重复模板编写工作,真是太不爽了。接口提供了,还要自己创建成实体类,然后还要加装饰器进行属性参数的设置。非常烦躁!

这几天实在受不了这个重复无效的工作了!于是开始着手编写一个工具,来减少重复模板代码的编写。

优化前后展示

优化前代码:

@InputType({ description: 'This is User where input' })
export class UserWhereInput implements Prisma.UserWhereInput {
  @Field((type) => [UserWhereInput], { nullable: true })
  AND?: UserWhereInput[];

  @Field((type) => [UserWhereInput], { nullable: true })
  OR?: UserWhereInput[];

  @Field((type) => [UserWhereInput], { nullable: true })
  NOT?: UserWhereInput[];

  @Field((type) => StringFilter, { nullable: true })
  id?: StringFilter;

  @Field((type) => StringFilter, { nullable: true })
  username?: StringFilter;

  @Field((type) => StringFilter, { nullable: true })
  email?: StringFilter;

  @Field((type) => StringFilter, { nullable: true })
  phone?: StringFilter;

  /// More fields...

优化后:

@InputTypeBuilder(
  { description: 'User where input' },
  FieldsBuilderOptionHelper(
    ['id', 'username', 'email', 'phone', /* ...more fields */],
    () => StringFilter,
    { nullable: true },
  ),
)
export class UserWhereInput extends InterfaceTransformAbstract<Prisma.UserWhereInput>>() {}

嗯舒服了!

还是装饰器?

是的呢!本来想直接从 Prisma scherma 中进行实体类的 CLI 生成,但是实在没时间研究 Prisma 的 AST,索性使用自己编写装饰器来实现重复繁琐的数据字段设置操作。

包叫什么?

@bytegem/nest-gql-mix

如何安装?

npm i @bytegem/nest-gql-mix 

可以省去的工作量有多少?

这要看你的 Model 字段类型有多少,这个包的装饰器按照字段类型进行 GraphQL type fields 的生成。

理论上来说,你 Model 的字段类型越少,节省的编码时间越多(无效编码时间和代码量相应减少),甚至 Entity 只需要创建一个空类即可。

GitHub

这个包采用 MIT 协议开源,地址👉github.com/bytegem/nest-gql-mix

🌟

如果喜欢,亲不要吝啬你的 Star 哦!

Seven 的代码太渣,欢迎关注我的新拓展包 medz/cors 解决 PHP 项目程序设置跨域需求。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!