NestJS 最早在 2017.1 月立项,2017.5 发布第一个正式版本,它是一个基于 Express,使用 TypeScript 开发的后端框架。设计之初,主要用来解决开发 Node.js 应用时的架构问题,灵感来源于 Angular。在本文中,我将粗略介绍 NestJS 中的一些亮点。
组件容器
NestJS 采用组件容器的方式,每个组件与其他组件解耦,当一个组件依赖于另一组件时,需要指定节点的依赖关系才能使用:
import { Module } from '@nestjs/common'; import { CatsController } from './cats.controller'; import { CatsService } from './cats.service'; import { OtherModule } from '../OtherModule'; @Module({ imports: [OtherModule], controllers: [CatsController], providers: [CatsService], }) export class CatsModule {}
依赖注入(DI)
与 Angular 相似,同是使用依赖注入的设计模式开发
当使用某个对象时,DI 容器已经帮你创建,无需手动实例化,来达到解耦目的:
// 创建一个服务 @Inject() export class TestService { public find() { return 'hello world'; } } // 创建一个 controller @Controller() export class TestController { controller( private readonly testService: TestService ) {} @Get() public findInfo() { return this.testService.find() } }
为了能让 TestController
使用 TestService
服务,只需要在创建 module 时,作为 provider 写入即可:
@Module({ controllers: [TestController], providers: [TestService], }) export class TestModule {}
当然,你可以把任意一个带 @Inject()
的类,注入到 module 中,供此 module 的 Controller 或者 Service 使用。
背后的实现基于 Decorator + Reflect Metadata,详情可以查看深入理解 TypeScript - Reflect Metadata 。
细粒化的 Middleware
在使用 Express 时,我们会使用各种各样的中间件,譬如日志服务、超时拦截,权限验证等。在 NestJS 中,Middleware 功能被划分为 Middleware、Filters、Pipes、Grards、Interceptors。
例如使用 Filters,来捕获处理应用中抛出的错误:
@Catch() export class AllExceptionsFilter implements ExceptionFilter { catch(exception: any, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const request = ctx.getRequest(); const status = exception.getStatus(); // 一些其他做的事情,如使用日志 response .status(status) .json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, }); } }
使用 interceptor,拦截 response 数据,使得返回数据格式是 { data: T }
的形式:
import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; export interface Response<T> { data: T; } @Injectable() export class TransformInterceptor<T> implements NestInterceptor<T, Response<T { intercept( context: ExecutionContext, call$: Observable<T>, ): Observable<Response<T { return call$.pipe(map(data => ({ data }))); } }
使用 Guards,当不具有 'admin' 角色时,返回 401:
import { ReflectMetadata } from '@nestjs/common'; export const Roles = (...roles: string[]) => ReflectMetadata('roles', roles); @Post() @Roles('admin') async create(@Body() createCatDto: CreateCatDto) { this.catsService.create(createCatDto); }
数据验证
得益于class-validator 与class-transformer 对传入参数的验证变的非常简单:
// 创建 Dto export class ContentDto { @IsString() text: string } @Controller() export class TestController { controller( private readonly testService: TestService ) {} @Get() public findInfo( @Param() param: ContentDto // 使用 ) { return this.testService.find() } }
当所传入参数 text 不是 string 时,会出现 400 的错误。
GraphQL
GraphQL 由 facebook 开发,被认为是革命性的 API 工具,因为它可以让客户端在请求中指定希望得到的数据,而不像传统的 REST 那样只能在后端预定义。
NestJS 对 Apollo server 进行了一层包装,使得能在 NestJS 中更方便使用。
在 Express 中使用 Apollo server 时:
const express = require('express'); const { ApolloServer, gql } = require('apollo-server-express'); // Construct a schema, using GraphQL schema language const typeDefs = gql` type Query { hello: String } `; // Provide resolver functions for your schema fields const resolvers = { Query: { hello: () => 'Hello world!', }, }; const server = new ApolloServer({ typeDefs, resolvers }); const app = express(); server.applyMiddleware({ app }); const port = 4000; app.listen({ port }, () => console.log(`Server ready at http://localhost:${port}${server.graphqlPath}`), );
在 NestJS 中使用它:
// test.graphql type Query { hello: string; } // test.resolver.ts @Resolver() export class { @Query() public hello() { return 'Hello wolrd'; } }
使用 Decorator 的方式,看起来也更 TypeScript
。
其他
除上述一些列举外,NestJS 实现微服务开发、配合 TypeORM 、以及 Prisma 等特点,在这里就不展开了。
参考
深入理解 TypeScript - Reflect Metadata
Egg VS NestJS
NestJS 官网
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。