0
0
NestJSframework~5 mins

WebSocket guards and pipes in NestJS

Choose your learning style9 modes available
Introduction

WebSocket guards and pipes help control and process data in real-time communication. Guards check if a user can connect or send messages, while pipes clean or transform the data before use.

When you want to allow only certain users to connect to your WebSocket server.
When you need to check user permissions before processing a WebSocket message.
When you want to validate or transform incoming message data before handling it.
When you want to reject bad or incomplete data early to keep your app safe.
When you want to keep your WebSocket code clean by separating checks and data processing.
Syntax
NestJS
import { CanActivate, ExecutionContext, Injectable, PipeTransform, ArgumentMetadata } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

@Injectable()
export class MyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const client = context.switchToWs().getClient();
    // Your logic here
    return true; // or false to block
  }
}

@Injectable()
export class MyPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // Your transformation or validation here
    return value; // or throw new WsException('Error message')
  }
}

Guards must return true to allow the action or false to block it.

Pipes can modify data or throw exceptions to stop processing.

Examples
This guard checks if the client sent a correct token before allowing connection.
NestJS
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const client = context.switchToWs().getClient();
    const token = client.handshake.auth.token;
    if (token === 'secret') {
      return true;
    }
    throw new WsException('Unauthorized');
  }
}
This pipe checks if the incoming message has a text property that is a string.
NestJS
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

@Injectable()
export class ValidateMessagePipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (!value.text || typeof value.text !== 'string') {
      throw new WsException('Invalid message format');
    }
    return value;
  }
}
Sample Program

This example shows a WebSocket gateway that uses a guard to allow only clients with the correct token. It also uses a pipe to check that incoming messages have a valid text string. If both pass, it returns a confirmation message.

NestJS
import { WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket, WsException, UseGuards, UsePipes } from '@nestjs/websockets';
import { Socket } from 'socket.io';
import { Injectable, CanActivate, ExecutionContext, PipeTransform, ArgumentMetadata } from '@nestjs/common';

@Injectable()
class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const client = context.switchToWs().getClient<Socket>();
    const token = client.handshake.auth.token;
    if (token === 'secret') {
      return true;
    }
    throw new WsException('Unauthorized');
  }
}

@Injectable()
class ValidateMessagePipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (!value.text || typeof value.text !== 'string') {
      throw new WsException('Invalid message format');
    }
    return value;
  }
}

@WebSocketGateway()
export class ChatGateway {
  @UseGuards(AuthGuard)
  @UsePipes(ValidateMessagePipe)
  @SubscribeMessage('message')
  handleMessage(@MessageBody() data: { text: string }, @ConnectedSocket() client: Socket): string {
    return `Received: ${data.text}`;
  }
}
OutputSuccess
Important Notes

Always throw WsException in guards or pipes to send error messages to clients.

Use @UseGuards() and @UsePipes() decorators to apply guards and pipes on WebSocket handlers.

Guards run before pipes, so permission checks happen before data validation.

Summary

Guards control who can connect or send messages.

Pipes check and transform message data before use.

Use them together to keep your WebSocket app safe and clean.