Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Nest Advanced

ASecurity

GraphQL, WebSockets, and microservices patterns for NestJS. Apply only when the relevant package is in dependencies (`@nestjs/graphql`, `@nestjs/websockets`, `@nestjs/microservices`). Each section is orientation, not exhaustive — defer to NestJS docs for deep dives. Use this skill to: - Wire a GraphQL resolver (code-first) with class-validator inputs. - Build a WebSocket gateway with auth and room management. - Set up a microservice transport (TCP/RabbitMQ/NATS/Redis/Kafka) and message handl...

35 stars
0 votes
0 copies
0 views
Added 9/22/2026
businesstypescriptnodesecurity

Works with

cli

Security Analysis

A100/100

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add AratKruglik/claude-sdlc --skill nest-advanced --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Nest Advanced?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Nest Advanced
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aratkruglik-nest-advanced/badge)](https://www.skillsdirectory.com/skills/aratkruglik-nest-advanced)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: nest-advanced
description: |
  GraphQL, WebSockets, and microservices patterns for NestJS. Apply only when the relevant package is in dependencies (`@nestjs/graphql`, `@nestjs/websockets`, `@nestjs/microservices`). Each section is orientation, not exhaustive — defer to NestJS docs for deep dives.

  Use this skill to:
  - Wire a GraphQL resolver (code-first) with class-validator inputs.
  - Build a WebSocket gateway with auth and room management.
  - Set up a microservice transport (TCP/RabbitMQ/NATS/Redis/Kafka) and message handlers.

  Do NOT use this skill for:
  - REST controllers (see nest-conventions + decorator-patterns).
  - ORM (see nest-data-layer).
  - Auth strategies (see security-analyst phase guidance).
user-invocable: false
paths: ["src/**/*.ts"]
---

# NestJS Advanced Surfaces

This skill covers the three advanced surfaces NestJS supports beyond REST. Each is opt-in via package presence — do not introduce these surfaces speculatively.

## GraphQL (`@nestjs/graphql`)

### Module setup (code-first, modern default)

```ts
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql',         // or `true` for in-memory
      sortSchema: true,
      playground: process.env.NODE_ENV !== 'production',
      context: ({ req }) => ({ req }),
    }),
  ],
})
export class AppModule {}
```

### ObjectType (return types)

```ts
@ObjectType()
export class User {
  @Field(() => ID)
  id!: string;

  @Field()
  email!: string;

  @Field({ nullable: true })
  name?: string;

  @Field(() => [Order])
  orders!: Order[];
}
```

- `@Field()` — exposes the property; type inferred from TypeScript when possible.
- For arrays/non-primitive types, pass the explicit type: `@Field(() => [Order])`.
- `nullable: true` for optional fields; matches TS `?:` modifier.

### InputType (mutation inputs)

```ts
@InputType()
export class CreateUserInput {
  @Field()
  @IsEmail()
  email!: string;

  @Field()
  @MinLength(8)
  password!: string;
}
```

InputType + class-validator works alongside the global ValidationPipe for runtime checks.

### Resolver

```ts
@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly users: UsersService) {}

  @Query(() => User, { nullable: true })
  user(@Args('id', { type: () => ID }) id: string) {
    return this.users.findById(id);
  }

  @Query(() => [User])
  users() {
    return this.users.findAll();
  }

  @Mutation(() => User)
  createUser(@Args('input') input: CreateUserInput) {
    return this.users.create(input);
  }

  @ResolveField(() => [Order])
  orders(@Parent() user: User) {
    return this.users.ordersByUserId(user.id);
  }
}
```

### Auth in GraphQL

`@UseGuards()` on resolvers and field resolvers. Use `GqlExecutionContext` in guards:

```ts
@Injectable()
export class GqlAuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    const req = ctx.getContext().req;
    return !!req.user;
  }
}
```

For custom param decorators in GraphQL, use:

```ts
export const CurrentUser = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().req.user,
);
```

### N+1 — DataLoader

```ts
@Injectable({ scope: Scope.REQUEST })
export class OrdersLoader {
  constructor(private readonly orders: OrdersService) {}

  readonly byUserId = new DataLoader<string, Order[]>(async (userIds) => {
    const orders = await this.orders.findByUserIds([...userIds]);
    return userIds.map((id) => orders.filter((o) => o.userId === id));
  });
}
```

Inject in resolver, use in `@ResolveField`. Avoids N+1 on `User.orders` across a list query.

### Federation pointer

`@nestjs/apollo` supports Apollo Federation v2 via `ApolloFederationDriver` + `@apollo/subgraph`. If the project uses federation (`@key` directives, multiple subgraphs), defer to NestJS Federation docs — patterns are stable but extensive.

### Schema-first variant

If the project uses schema-first (legacy or specific tooling), `.graphql` files drive types and `@Resolver` classes implement them via `@nestjs/graphql` codegen. Match what exists; don't migrate without BA approval.

## WebSockets (`@nestjs/websockets`)

### Gateway

```ts
import { WebSocketGateway, WebSocketServer, SubscribeMessage, MessageBody, ConnectedSocket, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';

@WebSocketGateway({
  cors: { origin: process.env.WS_ORIGIN ?? '*' },
  namespace: 'chat',
})
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server!: Server;

  handleConnection(client: Socket) {
    // auth on connection — read token from handshake
  }

  handleDisconnect(client: Socket) {
    // cleanup
  }

  @SubscribeMessage('message')
  async onMessage(
    @MessageBody() payload: SendMessageDto,
    @ConnectedSocket() client: Socket,
  ): Promise<{ ok: true }> {
    this.server.to(payload.roomId).emit('message', { from: client.id, text: payload.text });
    return { ok: true };
  }
}
```

### Auth on connection

WebSocket auth is NOT covered by HTTP guards by default. Pattern:

1. Client sends token in `handshake.auth.token` (Socket.io) or `Sec-WebSocket-Protocol` (raw WS).
2. Gateway's `handleConnection(client)` validates synchronously; on failure, `client.disconnect(true)`.
3. Subsequent messages can rely on `client.data.user` populated at connect.

Or use `@UseGuards(WsJwtGuard)` per `@SubscribeMessage` — guard implements `canActivate` reading from socket handshake.

### Room management

```ts
client.join(`room:${roomId}`);
client.leave(`room:${roomId}`);
this.server.to(`room:${roomId}`).emit('event', payload);
```

Rooms are cheap; cleanup happens automatically on disconnect.

### Validation

DTOs work the same — global ValidationPipe applies if enabled at app level. For Socket.io, payload arrives as parsed JSON; class-transformer + class-validator validate normally.

### Adapters

`@nestjs/platform-socket.io` is the default. For raw `ws`, install `@nestjs/platform-ws` and `app.useWebSocketAdapter(new WsAdapter(app))`. For Redis-backed pub/sub across instances, install `@socket.io/redis-adapter` and configure in `IoAdapter` subclass.

## Microservices (`@nestjs/microservices`)

### Transports

| Transport | Use case |
|---|---|
| `Transport.TCP` | Simple node-to-node, no broker |
| `Transport.RMQ` (RabbitMQ) | Reliable queues, work distribution |
| `Transport.NATS` | High-throughput, lightweight messaging |
| `Transport.REDIS` | Pub/sub, simple event broadcasting |
| `Transport.KAFKA` | Event sourcing, log-based |
| `Transport.MQTT` | IoT |
| `Transport.GRPC` | Strongly-typed RPC, polyglot services |

### Hybrid app (HTTP + microservice)

```ts
// src/main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.connectMicroservice<MicroserviceOptions>({
    transport: Transport.RMQ,
    options: {
      urls: [process.env.RABBITMQ_URL!],
      queue: 'orders_queue',
      queueOptions: { durable: true },
      prefetchCount: 1,
    },
  });

  await app.startAllMicroservices();
  await app.listen(3000);
}
```

### Standalone microservice

```ts
async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
    transport: Transport.NATS,
    options: { servers: ['nats://localhost:4222'] },
  });
  await app.listen();
}
```

### Patterns

```ts
// request-response (returns)
@MessagePattern({ cmd: 'find_user' })
findUser(@Payload() dto: FindUserDto, @Ctx() context: RmqContext) {
  return this.users.findById(dto.id);
}

// fire-and-forget event
@EventPattern('order.placed')
async handleOrderPlaced(@Payload() event: OrderPlacedEvent) {
  await this.email.sendOrderConfirmation(event);
}
```

### Calling microservices from a service

```ts
@Injectable()
export class OrdersService {
  constructor(@Inject('USERS_SERVICE') private readonly usersClient: ClientProxy) {}

  async createOrder(userId: string, items: OrderItem[]) {
    const user = await firstValueFrom(this.usersClient.send({ cmd: 'find_user' }, { id: userId }));
    // ... use user
    this.usersClient.emit('order.placed', { userId, items });
  }
}
```

Register the client in module `providers`:

```ts
@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'USERS_SERVICE',
        transport: Transport.RMQ,
        options: { urls: [process.env.RABBITMQ_URL!], queue: 'users_queue' },
      },
    ]),
  ],
})
```

### Acknowledgement and retries (RabbitMQ)

By default RabbitMQ auto-acks. For retry-safe handling, set `noAck: false` and ack manually:

```ts
@EventPattern('order.placed')
async handle(@Payload() data: any, @Ctx() ctx: RmqContext) {
  const channel = ctx.getChannelRef();
  const msg = ctx.getMessage();
  try {
    await this.process(data);
    channel.ack(msg);
  } catch {
    channel.nack(msg, false, true);     // requeue
  }
}
```

### Common pitfalls

- **Forgetting to start microservices** in hybrid app — `await app.startAllMicroservices()` BEFORE `app.listen()`.
- **Returning vs emitting** — `MessagePattern` for request-response; `EventPattern` for fire-and-forget. Mixing them causes hangs.
- **Serialization** — payloads must be JSON-serializable for most transports. Dates serialize as strings; class instances lose prototype.
- **Backpressure** in Kafka/RabbitMQ — set prefetch / max in-flight to avoid overwhelming consumers.
- **No global pipes by default in microservices** — apply `@UsePipes(new ValidationPipe())` per handler or via `app.useGlobalPipes()` on the microservice instance.

## Anti-patterns (all surfaces)

- ❌ Mixing GraphQL and REST for the same resource without a clear boundary.
- ❌ WebSocket auth via cookies only (no fallback for native clients).
- ❌ Microservice handlers blocking on long DB calls without backpressure.
- ❌ Treating GraphQL field resolvers as cheap when they trigger DB roundtrips (use DataLoader).
- ❌ Putting business logic in resolvers/gateways/handlers — always delegate to services.

Attribution

AratKruglikAratKruglik
View sourceMore from AratKruglik →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Solution Architect

Designs system architecture, component specifications, and technical integration strategy. Use when: designing solutions, system architecture, technology stack, or integration approaches.

192 votes

Akorchak:Venture Assessment

Generate a comprehensive VC investment assessment report for a company

72 votes

Telegram Compose

Compose rich, readable Telegram messages using HTML formatting via direct Telegram API. Use when: (1) Sending any Telegram message beyond a simple one-line reply, (2) Creating structured messages with sections, lists, or status updates, (3) Need formatting unavailable via Clawdbot's Markdown conversion (underline, spoilers, expandable blockquotes, user mentions by ID), (4) Sending alerts, reports, summaries, or notifications to Telegram, (5) Want professional, scannable message formatting wit...

6511 votes

Stock Analysis

Analyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management (create, add, remove assets), crypto analysis (Top 20 by market cap), and periodic performance reports (daily/weekly/monthly/quarterly/yearly). 8 analysis dimensions for stocks, 3 for crypto. Use for stock analysis, portfolio tracking, earnings reactions, or crypto monitoring.

6511 votes

Just Fucking Cancel

Find and cancel unwanted subscriptions by analyzing bank transactions. Detects recurring charges, calculates annual waste, and helps you cancel with direct URLs and browser automation. Use when: 'cancel subscriptions', 'audit subscriptions', 'find recurring charges', 'what am I paying for', 'save money', 'subscription cleanup', 'stop wasting money'. Supports CSV import (Apple Card, Chase, Amex, Citi, Bank of America, Capital One, Mint, Copilot) OR Plaid API for automatic transaction pull. Out...

6511 votes
View all in business →