看遍了koa,express以及其衍生框架之后,发现NodeJs的Web开发框架似乎跳不出一个固定的模式,这个问题也困扰着PHP,那就是能不能通过注解来简化开发?
实际上PHP是有“注解”的,不过是通过反射读取注释实现,非常低级。
今天要讲的是一个划时代的NodeJs Web框架——nestjs
示例代码
在介绍nestjs之前,先让大家看一看nestjs的示例代码。
- HTTP接口
@Controller('socket')
@UseGuards(AdminGuard)
export class SocketController {
private logger: Logger = new Logger(SocketController.name);
constructor(private readonly gateway: SocketGateway,
private readonly salesmanService: SalesmanService,
private readonly hashidService: HashidService) {
}
@Post('interaction')
async send(@Query('salesman_id') salesmanId: number, @Query('user_id') userId: number, @Body('content') content: string) {
if (!salesmanId || !userId || !content) {
throw new BadRequestException('Bad Request');
}
const salesman = await this.salesmanService.findById(salesmanId);
if (!salesman) {
throw new NotFoundException('销售不存在');
}
const roomId = this.salesmanService.makeSyncRoomKey(salesman);
this.gateway.namespace.to(roomId).emit(SocketEvent.OnInteraction, { user_id: this.hashidService.encode(userId), content });
return { errmsg: 'ok', errcode: 0 };
}
}
- Socket.IO
@UseFilters(new WsExceptionFilter())
@WebSocketGateway({ namespace: 'socket', adapter: adapter(appConfig.redis) })
export class SocketGateway implements OnGatewayInit<SocketIO.Namespace>, OnGatewayConnection<SocketIO.Socket> {
private logger: Logger = new Logger(SocketGateway.name);
@WebSocketServer() public readonly namespace: SocketIO.Namespace;
public adapter: adapter.RedisAdapter;
constructor(
private readonly salesmanService: SalesmanService,
private readonly corporationService: CorporationService,
private readonly hashidService: HashidService,
private readonly userService: UserService,
private readonly roomService: RoomService,
private readonly messageService: MessageService,
private readonly readService: ReadService,
private readonly memberService: MemberService,
) {
}
afterInit(server: SocketIO.Namespace): any {
this.adapter = server.adapter as adapter.RedisAdapter;
this.logger.log(`initialized ${server.name}`);
}
/**
* 进入聊天室
* @param {SocketIO.Socket} client
* @returns {any}
*/
async handleConnection(client: SocketIO.Socket): Promise<any> {
const { user_id, token, corporation_id, sign } = qs.parse(url.parse(client.request.url).query) as {
[name: string]: string;
};
if (!user_id && !token && !corporation_id && !sign) {
client.disconnect(true);
return;
}
const realUserId = this.hashidService.decode(user_id);
await promisify(client.join.bind(client))(this.roomService.makePersonalRoomId(realUserId)),
client.emit(SocketEvent.Ready);
}
@SubscribeMessage(SocketEvent.Join)
handleJoin(client: SocketIO.Socket, data: any) {
if (JoinType.Chat === data.type) {
return this.handleJoinChat(client, data);
}
if (JoinType.Sync === data.type) {
return this.handleJoinSync(client, data);
}
client.disconnect(true);
}
@SubscribeMessage(SocketEvent.Leave)
async handleLeave(client: SocketIO.Socket, data: any) {
const { user_id, token, corporation_id, sign } = qs.parse(url.parse(client.request.url).query) as {
[name: string]: string;
};
if (JoinType.Chat === data.type) {
await promisify(client.leave.bind(client))(data.room_id);
return { event: SocketEvent.Leave, data };
}
const isPersonal = user_id && token;
const roomId = isPersonal
? await this.salesmanService.getRoomId(user_id, token)
: await this.corporationService.getRoomId(corporation_id, sign);
if (roomId) {
await promisify(client.leave).bind(client)(roomId);
}
return { event: SocketEvent.Leave, data };
}
// ...
写法是不是很像Java?或者说是Angular4?
介绍
实际上nestjs的架构源自于java的spring框架,而代码组织则借鉴与Angular4的Module。
nestjs模块架构图
开始开发
yarn global add @nestjs/cli
nest new projectName
cd projectName && yarn start
写在最后
由于篇幅关系,nestjs的详细文档可以前往官网查看,本文只是做个框架介绍,开启新世界的大门。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。