注册
web

来自全韩国最好的程序员的 Nest.js 中 TypeSafe 方案

Nest.js 中的 TypeSafe 方案


在现代 Web 开发中,类型安全(TypeSafe)是提升代码质量和减少运行时错误的关键因素。


Nest.js 作为一个渐进式的 Node.js 框架,结合了 TypeScript 的强大功能,提供了构建高效、可扩展服务器端应用的理想平台。


笔者在使用 Nest.js 构建全栈应用时最大的痛点是写了这么多类型检查,好像没有办法和前端通用啊~。相信许多人也有这个问题,所以也冒出了在 Nest.js 中集成 tRPC 的教程。


而本文介绍的 Nestia,一个专为 Nest.js 设计的类型安全解决方案,帮助开发者在构建应用时实现更高的类型安全性和开发效率。


韩国最好的程序员


Jeongho Nam,GitHub用户名为 samchon他在 README 中自称为韩国最好的程序员。他自1998年开始编程,拥有25年的丰富经验。在这段时间里,他开发了许多程序,并不断提升自己的技能。他不仅在工作中开发程序,还在业余时间开发开源项目,以满足自身需求或改进现有功能。这些开源项目逐渐形成了新的开源库,其中最著名的就是 typianestia


什么是Nestia?


Nestia 是一个专为 Nest.js 开发的库,旨在通过利用 TypeScript 的类型系统,提供更高效和类型安全的开发体验。Nestia 的核心目标是简化数据传输对象(DTOs)的定义和验证,减少类型错误,并提升代码的可维护性。


Nestia的主要功能



  1. 类型安全的 DTO 定义和验证

    Nestia 利用 TypeScript 的类型系统,允许开发者定义类型安全的 DTOs。通过自动生成的类型定义,Nestia 确保了数据在传输和处理过程中的一致性,避免了常见的类型错误。


    NestJS需要三个重复的 DTO 模式定义。第一个是定义 TypeScript 类型,第二个和第三个是调用 class-validator@nestjs/swagger 的装饰器函数。这不仅繁琐,而且容易出错。如果你在第 2 或第 3 处写错了的话,TypeScript 编译器是无法检测到的。只有在运行时才能检测到。换句话说,它并不是类型安全的。


  2. 自动生成API客户端

    Nestia 可以根据服务器端的 API 定义,自动生成类型安全的 API 客户端。这种方式不仅减少了手动编写客户端代码的工作量,还确保了前后端的一致性


    这一功能与著名的 tRPC 库有相似之处。tRPC 是一个端到端类型安全的 RPC 框架,它允许你轻松构建和使用完全类型安全的 API,无需模式或代码生成。tRPC 的主要作用是在全栈 TypeScript 项目中提供类型安全的 API 调用,大大提高了开发效率和代码质量。但 tRPC 的问题是通常要求前后端代码位于同一个 monorepo 中,以便共享类型定义。这种紧耦合的架构可能不适合所有项目,特别是那些前后端分离开发或需要为第三方提供 API 的场景。相比之下,Nestia 通过自动生成独立的 API 客户端解决了这个问题。它允许你在保持类型安全的同时,将生成的 SDK 作为独立的包分发给客户端开发者。这种方式既保留了类型安全的优势,又提供了更大的灵活性,使得 Nestia 在更广泛的项目结构和开发场景中都能发挥作用。


  3. 高效的JSON序列化和反序列化

    Nestia 提供了高效的 JSON 序列化和反序列化功能,利用 TypeScript 的类型信息,显著提升了性能和类型安全性。



如何使用Nestia


安装Nestia


你可以运行以下命令通过模版代码来快速上手 Nestia。
模板将自动构建在<directory>中。作为参考,这是一个最小的模板项目,只集中于从 NestJS 服务器生成 SDK。它不包含数据库连接。


npx nestia start <directory>

你也可以运行下面的命令来将 Nestia 集成至现有的项目中。设置向导将自动安装并配置所有内容。


npx nestia setup

定义类型安全的DTO


你不需要掌握特殊的语法只使用 TypeScript 就可以编写一个带有类型检查的 DTO。当然,Nestia 也通过 Typia 提供了编写复杂类型检查的可能,例如,我们可以定义一个论坛完整的 DTO:


import { tags } from "typia";

export interface IBbsArticle {
/* Primary Key. */
id: string & tags.Format<"uuid">;

/* Title of the article. */
title: null | (string & tags.MinLength<5> & tags.MaxLength<100>);

/* Main content body of the article. */
body: string;

/* Creation time of article. */
created_at: string & tags.Format<"date-time">;
}


Controller 中调用 Nestia 的装饰器


NestJS 原生的装饰器(如 @Get(), @Post() 等)虽然使用方便,但在性能和类型安全方面存在一些局限:



  • 使用 class-validator 和 class-transformer 进行验证和转换,性能相对较低
  • 需要定义额外的 DTO 类和装饰器,增加了代码量
  • 类型安全性不够强,运行时可能出现类型错误

Nestia 的装饰器(如 @TypedRoute.Get(), @TypedBody() 等)则解决了这些问题:



  • 利用 typia 库进行高性能的运行时类型验证,比 class-validator 快 20,000 倍
  • 支持使用纯 TypeScript 接口定义 DTO,无需额外的类定义
  • 在编译时进行类型检查,提供更强的类型安全性
  • JSON 序列化速度比 class-transformer 快 200 倍

import { TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";

import { IBbsArticle } from "./IBbsArticle";

@Controller("bbs/articles")
export class BbsArticlesController {

@TypedRoute.Get("random")
public async random(): Promise<IBbsArticle> {
return {
id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
title: "Hello nestia users",
body: "Just use `TypedRoute.Get()` function like this",
created_at: "2023-04-23T12:04:54.168Z",
files: [],
};
}

@TypedRoute.Post()
public async store(
@TypedBody() input: IBbsArticle.IStore,
): Promise<IBbsArticle> {
return {
...input,
id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
created_at: "2023-04-23T12:04:54.168Z",
};
}
}

自动生成API客户端


Nestia可以根据服务器端的API定义,自动生成类型安全的API客户端。在根目录配置 nestia.config.ts 文件


import { INestiaConfig } from '@nestia/sdk';
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';

import { AppModule } from './src/app.module';

const NESTIA_CONFIG: INestiaConfig = {
input: async () => {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.setGlobalPrefix('api');
return app;
},
output: 'src/api',
clone: true,
distribute: 'sdk',
};
export default NESTIA_CONFIG;

运行命令 npx nestia sdk 即可生成 SDK package,你可以直接在 Monorepo 中使用它,也可以将其分发到 npm.


尝试使用生成的 SDK 看到类型提示的那一刻,整个人都通畅了~


703_1x_shots_so.png


结论


Nestia 作为一个专为 Nest.js 设计的类型安全解决方案,通过简化 DTO 定义和验证、自动生成 API 客户端以及高效的 JSON 序列化和反序列化功能,帮助开发者在构建应用时实现更高的类型安全性和开发效率。无论是大型企业级应用还是个人项目,Nestia 都是提升代码质量和开发效率的理想选择。


通过本文的介绍,希望您对 Nestia 有了更深入的了解,并能在您的 Nest.js 项目中尝试使用这一强大的工具,享受类型安全带来的诸多好处。


作者:
来源:juejin.cn/post/7385728319738216488

0 个评论

要回复文章请先登录注册