NestJS相关问题
Why do we need dtos and interfaces both in nestjs
NestJS在设计模式上提倡使用Data Transfer Objects(DTOs)和接口(Interfaces)来实现应用程序逻辑的分离以及类型安全。1. DTOs(Data Transfer Objects)DTOs在NestJS中通常用于定义数据的传输格式。它们是用来约束客户端发送到服务器端的数据结构,确保数据的一致性和验证。DTOs通常带有装饰器(decorators),这些装饰器可以提供验证规则,确保只有符合这些规则的数据才被接受和处理。例子:假设我们有一个创建用户的API,我们可能会定义一个CreateUserDto类,来确保我们接收到的数据包含username和password,并且它们都是字符串:import { IsString } from 'class-validator';export class CreateUserDto { @IsString() readonly username: string; @IsString() readonly password: string;}在上面的例子中,class-validator库提供了@IsString()装饰器来验证传入数据的类型。2. 接口(Interfaces)接口在TypeScript和NestJS中用于定义对象的结构,它们是为了编译时的类型检查而存在。接口定义了对象可以有哪些属性以及这些属性的类型。它们不会编译到JavaScript中,因此不会在运行时提供任何的验证。例子:在服务或者模块之间共享数据结构时,我们可以定义一个接口来约定数据的形状。interface User { id: number; username: string; password: string;}在上述例子中,User接口描述了用户对象必须包含的属性和类型。任何实现了User接口的对象都必须有id,username和password这三个属性。为什么同时需要?使用DTOs和接口结合起来可以带来以下优势:分层的数据验证:DTOs可以在应用层对传入的数据进行严格的验证,而接口则在编译时提供类型检查,确保代码的正确性。代码可维护性:接口提供了一个清晰的契约定义,可以被服务、控制器和其他类实现,这使得代码更加模块化和可维护。灵活性和扩展性:DTOs可以为特定的操作定义数据格式,例如创建、更新,而接口则定义了应用程序级别的数据模型。这两者的结合使得扩展和重构变得更加容易。隔离变化:如果来自外部的数据需求变化,通常只需要调整DTO,而不需要修改内部使用的接口,这样可以最小化变化对系统的影响。综上所述,DTOs和接口共同为NestJS提供了一个灵活、可靠和可维护的数据处理框架。通过在编译时和运行时各自发挥作用,它们确保了类型安全和数据一致性,同时也提高了代码的可读性和维护性。
答案6·阅读 276·2024年2月20日 19:17
Whats the difference between interceptor vs middleware vs filter in nest js
正如您已经在问题中描述的那样,这三个都是非常相似的概念,在很多情况下很难决定,这取决于您的偏好。但我可以概述一下这些差异:拦截器拦截器可以在调用路由处理程序之前和之后访问响应/请求。登记@UseInterceptors()直接在具有控制器或方法范围的控制器类中全球范围 app.useGlobalInterceptors()内 main.ts例子LoggingInterceptor:在路由处理程序之前请求,在其结果之后请求。测量需要的时间。ResultMapping:转换 null为 []或将结果包装在响应对象中:users->{users: users}结论与中间件相比,我喜欢注册更接近路由处理程序。但存在一些限制,例如,当您在路由处理程序中发送 response特定于库的对象时,您无法设置响应代码或使用拦截器更改响应,请参阅文档。@Res()中间件仅在调用路由处理程序之前调用中间件。您可以访问响应对象,但没有路由处理程序的结果。它们基本上是表达中间件功能。登记在模块中,选择相关路由的方式非常灵活(使用通配符,按方法,…)全球范围 app.use()内 main.ts例子FrontendMiddleware:将除 API 之外的所有路由重定向到 index.html,请参阅此线程您可以使用任何现有的快速中间件。有很多图书馆,例如body-parser或morgan结论中间件的注册非常灵活,例如:适用于除一个之外的所有路由等。但由于它们是在模块中注册的,因此当您查看其方法时,您可能没有意识到它适用于您的控制器。您还可以利用现有的所有快速中间件库,这也很棒。异常过滤器异常过滤器在路由处理程序和拦截器之后调用。它们是响应发出之前最后进行更改的地方。登记@UseFilters()直接在具有控制器或方法范围的控制器类中全球范围 app.useGlobalFilters()内您的 main.ts例子UnauthorizedFilter:映射到用户易于理解的消息NotFoundFilter:将所有未找到的路由(不属于您的 api 的一部分)映射到您的 index.html.结论异常过滤器的基本用例是提供可理解的错误消息(隐藏技术细节)。但还有其他创造性的使用方式:当您提供单页面应用程序时,通常所有路由都应重定向到 index.html除 API 路由之外的路由。在这里,您可以重定向到 NotFoundException. 有些人可能会觉得这个很聪明,而另一些人可能觉得很老套。你的选择。;-)所以执行顺序是:中间件 -> 拦截器 -> 路由处理程序 -> 拦截器 -> 异常过滤器(如果抛出异常)对于这三个工具,您可以在其构造函数中注入其他依赖项(如服务等)。
答案3·阅读 138·2024年2月20日 19:16