在是用nodejs作为服务端语言的时候,之前我们会选择express或者koa作为服务框架。虽然es7的语法已经让javascript很类似java了,但是如果是习惯用Java的人来说,写起来是不太顺手,毕竟js的写法很多人还是适应不了的。最近看到有个新的框架 nestjs,于是看了下文档,感觉风格很像spring 于是打算写个demo试试。
1.初始化框架
yarn global add @nestjs/cli
nest new project-name
脚手架会生成一个基本的nestjs项目。里面有基本的hello word的应用。但是,这些还不够,一个完整的应用,我们需要有数据库,需要有配置管理。
2.配置管理
yarn add @nestjs/config
我们可以通过 @nestjs/config 来对项目的配置项进行管理。以数据库配置为例,我们在根目录下创建一个.env文件
.env
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=test
DB_PASSWORD=test
DB_DATABASE=test
然后创建配置的对象文件 src/config/configuration.ts
export default ()=>({
database:{
type: 'mysql',
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: ["dist/**/*.entity{.ts,.js}"],
synchronize: true,
}
})
在app.module.ts文件下加入
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config/configuration';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
load: [configuration],
})
]
})
export class AppModule {
}
至此配置部分就算完成了
3.数据库
nestjs 标配的orm框架是typeorm,所以,这里我们以mysql为例
yarn add @nestjs/typeorm typeorm mysql
先在数据库创建一个 orders表,因为只是测试 ,就只用一个id字段,插入一个1的数据。
根据上面的配置,我们在 src/domain/entity文件夹下创建一个 order.entity.ts文件
import { Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity('orders')
export class Order{
@PrimaryGeneratedColumn()
id: number;
}
在app.module.ts 中配置typeorm
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config/configuration';
import { Order } from './domain/entity/order.entity';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
load: [configuration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => configService.get('database'),
inject: [ConfigService],
}),
TypeOrmModule.forFeature([Order]),
]
})
export class AppModule {
}
这里可以看到,我们借助之前的config 进行了typeorm的配置。
4.业务编写
order.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Order } from '../domain/entity/order.entity';
import { Repository } from 'typeorm/index';
@Injectable()
export class OrderService{
constructor(
@InjectRepository(Order)
private orderRepository: Repository<Order>,
) {}
async queryById(id: number): Promise<Order> {
return await this.orderRepository.findOne(id)
}
}
order.controller.ts
import { Controller, Get, Inject, Param, Post } from '@nestjs/common';
import { OrderService } from '../service/order.service';
import { Order } from '../domain/entity/order.entity';
@Controller('admin-api/orders')
export class OrderController{
constructor(
@Inject(OrderService) private readonly orderService: OrderService
) {
}
@Get('one/:id')
async queryById(@Param('id') id):Promise<Order>{
return this.orderService.queryById(id)
}
}
完整的app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config/configuration';
import { Order } from './domain/entity/order.entity';
import { OrderController } from './controller/order.controller';
import { OrderService } from './service/order.service';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
load: [configuration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => configService.get('database'),
inject: [ConfigService],
}),
TypeOrmModule.forFeature([Order]),
],
controllers: [OrderController],
providers: [OrderService],
})
export class AppModule {
}
5.看看请求效果
从效果看,达到预期。至于其他的组件,例如fliter,middleware这些,根据实际情况,酌情引入。