使用NestJS开发Node.js应用的方法


Posted in Javascript onDecember 03, 2018

NestJS 最早在 2017.1 月立项,2017.5 发布第一个正式版本,它是一个基于 Express,使用 TypeScript 开发的后端框架。设计之初,主要用来解决开发 Node.js 应用时的架构问题,灵感来源于 Angular。在本文中,我将粗略介绍 NestJS 中的一些亮点。

组件容器

使用NestJS开发Node.js应用的方法

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 相似,同是使用依赖注入的设计模式开发

使用NestJS开发Node.js应用的方法

当使用某个对象时,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 官网

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript中的作用域scope介绍
Dec 28 Javascript
JsRender for index循环索引用法详解
Oct 31 Javascript
jQuery中的Deferred和promise 的区别
Apr 03 Javascript
js实现倒计时关键代码
May 05 Javascript
10个最优秀的Node.js MVC框架
Aug 24 Javascript
发布Angular应用至生产环境的方法
Dec 10 Javascript
微信小程序使用for循环动态渲染页面操作示例
Dec 25 Javascript
Vue起步(无cli)的啊教程详解
Apr 11 Javascript
Vue防止白屏添加首屏动画的实例
Oct 31 Javascript
Javascript异步流程控制之串行执行详解
Sep 27 Javascript
小程序实现列表倒计时功能
Jan 29 Javascript
create-react-app开发常用配置教程
Jun 25 Javascript
写gulp遇到的ES6问题详解
Dec 03 #Javascript
使用mpvue搭建一个初始小程序及项目配置方法
Dec 03 #Javascript
JS基于Location实现访问Url、重定向及刷新页面的方法分析
Dec 03 #Javascript
koa2实现登录注册功能的示例代码
Dec 03 #Javascript
react-router 路由切换动画的实现示例
Dec 03 #Javascript
Vue.js 中的 v-model 指令及绑定表单元素的方法
Dec 03 #Javascript
ng-zorro-antd 入门初体验
Dec 03 #Javascript
You might like
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
php实现json编码的方法
2015/07/30 PHP
作为程序员必知的16个最佳PHP库
2015/12/09 PHP
PHP实现的多维数组排序算法分析
2018/02/10 PHP
window.js 主要包含了页面的一些操作
2009/12/23 Javascript
javascript+css 网页每次加载不同样式的实现方法
2009/12/27 Javascript
jquery tab标签页的制作
2010/05/10 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
SyntaxHighlighter 3.0.83使用笔记
2015/01/26 Javascript
AngularJS向后端ASP.NET API控制器上传文件
2016/02/03 Javascript
Vue.js中用v-bind绑定class的注意事项
2016/12/13 Javascript
微信小程序实现无限滚动列表
2020/05/29 Javascript
Vue核心概念Action的总结
2019/01/18 Javascript
json数据格式常见操作示例
2019/06/13 Javascript
Python字符串特性及常用字符串方法的简单笔记
2016/01/04 Python
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
关于Python正则表达式 findall函数问题详解
2018/03/22 Python
python3库numpy数组属性的查看方法
2018/04/17 Python
Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】
2019/04/05 Python
Python+AutoIt实现界面工具开发过程详解
2019/08/07 Python
Python aiohttp百万并发极限测试实例分析
2019/10/26 Python
Python如何基于Tesseract实现识别文字功能
2020/06/05 Python
Html5新增标签有哪些
2017/04/13 HTML / CSS
戴尔马来西亚官网:Dell Malaysia
2020/05/02 全球购物
半年思想汇报
2013/12/30 职场文书
高三英语教学反思
2014/01/13 职场文书
古汉语文学求职信范文
2014/03/16 职场文书
新学期国旗下演讲稿
2014/05/08 职场文书
优秀员工演讲稿
2014/05/19 职场文书
工地标语大全
2014/06/18 职场文书
物流专业求职信
2014/06/30 职场文书
单位综合评价意见
2015/06/05 职场文书
我在伊朗长大观后感
2015/06/16 职场文书
小学运动会入场口号
2015/12/24 职场文书
uniapp 微信小程序 自定义tabBar 导航
2022/04/22 Javascript