当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 使用NestJS开发Node.js应用的方法

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

2019年06月01日  | 移动技术网IT编程  | 我要评论

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);
}

数据验证

得益于 与对传入参数的验证变的非常简单:

// 创建 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 官网

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网