使用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 相关文章推荐
键盘 keycode的值 javascript时触发事件时很有用的要素
Nov 02 Javascript
锋利的jQuery 第三章章节总结的例子
Mar 23 Javascript
HTML颜色选择器实现代码
Nov 23 Javascript
jquery实现可自动收缩的TAB网页选项卡代码
Sep 06 Javascript
jquery中val()方法是从最后一个选项往前读取的
Sep 06 Javascript
深入理解JavaScript内置函数
Jun 03 Javascript
AngularJS实现单独作用域内的数据操作
Sep 05 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
Oct 26 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
Jan 23 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
Dec 20 Javascript
基于node+websocket+html实现腾讯课堂聊天室聊天功能
Mar 04 Javascript
EXTJS7实现点击拖拉选择文本
Dec 17 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
短波收音机简介
2021/03/01 无线电
什么是MVC,好东西啊
2007/05/03 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
smarty自定义函数用法示例
2016/05/20 PHP
PHP数组式访问接口ArrayAccess用法分析
2017/12/28 PHP
jQuery实现折线图的方法
2015/02/28 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
2016/12/08 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
2017/02/21 Javascript
vue中各种通信传值方式总结
2019/02/14 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
2019/03/29 Javascript
vue滚动固定顶部及修改样式的实例代码
2019/05/30 Javascript
[03:59]DOTA2英雄梦之声_第07期_水晶室女
2014/06/23 DOTA
Python实现统计单词出现的个数
2015/05/28 Python
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
在python中按照特定顺序访问字典的方法详解
2018/12/14 Python
python itchat给指定联系人发消息的方法
2019/06/11 Python
Django REST Framework之频率限制的使用
2019/09/29 Python
python统计mysql数据量变化并调用接口告警的示例代码
2020/09/21 Python
python 用pandas实现数据透视表功能
2020/12/21 Python
浅谈html5增强的页面元素
2016/06/14 HTML / CSS
印尼太阳百货公司网站:Matahari
2018/02/04 全球购物
廉价连衣裙和婚纱礼服在线销售:Tbdress
2019/02/28 全球购物
电子信息专业自荐书
2014/02/04 职场文书
酒后驾车标语
2014/06/30 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
2014年人大工作总结
2014/12/10 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
夫妻吵架保证书
2015/05/08 职场文书
单位收入证明范本
2015/06/18 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
制定企业培训计划的五大要点!
2019/07/10 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript
python通过opencv调用摄像头操作实例分析
2021/06/07 Python
Opencv中cv2.floodFill算法的使用
2021/06/18 Python