Sử dụng Pipe, Exception Filter, Interceptor, Guard trong WebSocket Gateway
info
- Tương tự như HTTP, ở WebSocket Gateway ta cũng có thể sử dụng:
@UsePipes
: validate dữ liệu gửi đến từ client.@UseFilters
: xử lý lỗi được throw ra từ WebSocket@UseInterceptors
: dùng cho các nhiệm vụ như ghi log,...@UseGuards
: xác thực user trước khi xử lý event được gửi lên từ client,...
- Ta cũng có thể dùng chúng ở 2 cấp độ:
- Cho toàn bộ event
- Cho từng event cụ thể
Lưu ý
- Mặc dù ta đã cấu hình
APP_FILTER
,APP_PIPE
,APP_GUARD
,APP_INTERCEPTOR
ở file app.module.ts, nhưng mình không hiểu lý do gì nó chỉ đang hoạt động đối với HTTP, còn WebSocket thì phải chỉ định lại toàn bộ ở đầu Gateway (mục ví dụ dưới):
@Module({
providers: [
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
{ provide: APP_FILTER, useClass: HttpExceptionFilter },
{ provide: APP_PIPE, useClass: AppValidationPipe },
{ provide: APP_GUARD, useClass: AuthGuard },
{ provide: APP_INTERCEPTOR, useClass: AppClassSerializerInterceptor },
{ provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
],
})
export class AppModule {}
Ví dụ
@WebSocketGateway({ namespace: "/chat", cors: { origin: "*" } })
@UseFilters(AllExceptionsFilter, WsExceptionFilter)
@UseInterceptors(LoggingInterceptor)
@UseGuards(AuthGuard)
@UsePipes(
new ValidationPipe({
exceptionFactory: (errors) =>
new WsException({ message: "Invalid message data", errors }),
})
)
export class ChatGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
@WebSocketServer() server: Server;
private readonly logger = new Logger(ChatGateway.name);
afterInit(server: Server) {
this.logger.log("🚀 ChatGateway was established succesfully!");
}
handleConnection(client: Socket) {
console.log(`Client connected: ${client.id}`);
}
handleDisconnect(client: Socket) {
console.log(`Client disconnected: ${client.id}`);
}
@SubscribeMessage("sendMessage")
handleMessage(
client: Socket,
payload: { sender: string; message: string }
): WsResponse<string> {
this.server.emit("receiveMessage", data);
return {
event: "toClientEvent",
data: "Done",
};
}
}