NESTJS 服务化架构设计和项目搭建


创建项目很简单,nest-cli一键创建,关键是如何基于nestjs现有能力进行架构设计。

架构设计

项目背景

项目涉及的底层数据全部来自于公司的一个公共服务(jsf),该公共服务可对接口进行发布和订阅,同时提供各种协议的接口供第三方使用。我们的项目都是基于该服务提供的接口对数据进行二次加工和使用。

我的设想

我想构建的服务,类似微服务架构,有多个产品(ge和dm或者更多),各个产品之间有重合的业务,这部分需要共享,也有各自定制化的部分由各个产品自己管理,虽可能存在相互依赖,但需要独立部署。

基于以上思路,得到如下架构模型:
在这里插入图片描述

  • JSF-SERVER
    从公共服务获取数据,有多种方式获取(TCP、Http、RPC、Grpc),同时可以暴露http接口给客户端直接获取底层数据。(有些不需要二次加工的数据可以直接吐出)。第三方服务也可通过TCP协议与服务建立通信,获取数据。

  • Ge-server和Dm-server
    基础服务,暴露http接口给客户端使用

  • libs
    存放公共模块,比如登陆、鉴权、拦截器等

DEMO地址:

项目搭建

项目初始化

web 框架选择fastify代替Express,因其网络性能,详见附件性能评测

# 初始化项目
npm install @nestjs/cli -g
nest new nest-server-demo

# 安装依赖
npm uninstall @nestjs/platform-express
npm install @nestjs/{platform-fastify,microservices}  class-transformer class-validator --save

# 创建应用
nest g app ge
nest g app dm
nest g jsf

# 创建公共模块,修改前缀为@libs
nest g library common

改造微服务

暴露微服务

路径:apps/jsf/main.ts

declare const module: any;
import { NestFactory } from '@nestjs/core';
import { JsfModule } from './jsf.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(JsfModule, {
    transport: Transport.TCP,
    options: {
      port: 4000,
    },
  });

  await app.listen();
  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();

发布消息

  • 路径 apps/jsf/jsf.controller.ts
import { Controller, Get } from '@nestjs/common';
import { JsfService } from './jsf.service';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class JsfController {
  constructor(private readonly jsfService: JsfService) {}
  
  @MessagePattern({ cmd: 'getHelloX' })
  getHelloMessage(name: string): string {
    return this.jsfService.getHelloMessage(name);
  }
}

  • 路径 apps/jsf/jsf.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class JsfService {
  getHelloMessage(name: string): string {
    return `Hello ${name}!`;
  }
}

注册微服务

  • 路径:apps/ge/ge.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { GeController } from './ge.controller';
import { GeService } from './ge.service';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'NEST_SERVICE',
        transport: Transport.TCP,
        options: {
          port: 4000,
        },
      },
    ]),
  ],
  controllers: [GeController],
  providers: [GeService],
})
export class GeModule {}

注入微服务并调用

  • 路径 apps/ge/ge.service.ts
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { Observable } from 'rxjs';

@Injectable()
export class GeService {
  constructor(@Inject('NEST_SERVICE') private readonly client: ClientProxy) {}
  getHelloMessage(name: string): Observable<string> {
    return this.client.send<string>({ cmd: 'getHelloX' }, name);
  }
}

创建http接口供客户端使用

  • 路径:apps/ge/ge.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { GeService } from './ge.service';

@Controller()
export class GeController {
  constructor(private readonly geService: GeService) {}

  @Get(':name')
  getHello(@Param() params) {
    return this.geService.getHelloMessage(params.name);
  }
}

启动项目

安装concurrently,同时启动多应用并改造start脚本

"start": "concurrently --kill-others \"npm run start:ge\" \"npm run start:jsf\"",
"start:ge": "nest start ge --watch",
"start:jsf": "nest start jsf --watch",
"start:dm": "nest start dm --watch",
npm install concurrently -D
npm run start

防伪接口:localhost:3000/songmeinuo
注意:修改apps/dm/dm.main.ts的端口号,否则会冲突

建立代码规约

npm install kaqiinono-script -D
dm-rule

详见:
代码规范脚本自动化
利用npm bin创建可执行命令实现项目代码规范自动化

附录

web框架性能评测

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值