Chapter 10: Advanced Patterns
Mastering advanced patterns unlocks the full power of NestJS. This chapter covers CQRS, GraphQL, WebSockets, event sourcing, and real-world case studies for building scalable, modern applications. We’ll walk through practical examples and explain when to use each pattern.
10.1 CQRS (Command Query Responsibility Segregation)
CQRS separates read and write operations for better scalability and maintainability. Use the@nestjs/cqrs package for implementing CQRS in NestJS.
What is CQRS?
CQRS separates:- Commands: Write operations (create, update, delete)
- Queries: Read operations (get, list, search)
- Optimize reads and writes independently
- Scale read and write models separately
- Simplify complex domains
- Better performance
Think of CQRS as having two separate desks: one for taking orders (commands), and one for answering questions (queries). Each can be optimized for its specific purpose.
Installation
Command Example
Query Example
Using in Controller
Module Setup
- Use separate models for reads and writes
- Implement event sourcing for auditability
- Use CQRS for complex domains, not simple CRUD
- Keep commands and queries focused
10.2 GraphQL APIs
NestJS supports GraphQL out of the box. Use code-first or schema-first approaches. GraphQL lets clients request exactly the data they need.Installation
Code-First Approach
Resolver
Input DTO
Module Setup
- Use DTOs for input validation
- Leverage GraphQL subscriptions for real-time updates
- Document your schema for frontend teams
- Use DataLoader for N+1 query optimization
10.3 WebSockets & Real-Time Communication
WebSockets enable real-time, bidirectional communication. Use@nestjs/websockets for gateways and event handling.
Installation
WebSocket Gateway
Using with Authentication
- Chat applications
- Live dashboards
- Multiplayer games
- Real-time notifications
- Collaborative editing
10.4 Event Sourcing
Event sourcing stores state as a sequence of events. Useful for audit logs, undo/redo, and complex business flows.Event Store
Event Handler
- Store every change as an event
- Rebuild state by replaying events
- Separate write model (events) from read model (projections)
10.5 Real-World Case Study: Scalable Chat App
Let’s see how these patterns work together in a real-world scenario.Architecture
Features:- REST API for user management
- WebSocket gateway for real-time messaging
- CQRS for separating chat commands and queries
- Event sourcing for message history
- GraphQL for flexible data queries
Implementation
10.6 Best Practices
Following best practices ensures your advanced patterns are used effectively.When to Use Each Pattern
CQRS:- Complex domains with high read/write separation
- Need to optimize reads and writes independently
- Complex business logic
- Multiple frontend clients with different data needs
- Need flexible queries
- Real-time subscriptions required
- Real-time bidirectional communication
- Live updates needed
- Low latency requirements
- Need full audit trail
- Complex business flows
- Time travel/debugging needed
Don’t Over-Engineer
- Start simple
- Add complexity only when needed
- Use patterns that solve real problems
- Avoid premature optimization
Keep Code Modular
- Separate concerns
- Use dependency injection
- Write tests
- Document architecture
Monitor Performance
- Profile advanced features
- Monitor resource usage
- Set up alerts
- Optimize bottlenecks
10.7 Common Pitfalls
Avoid these common mistakes when using advanced patterns.Overengineering
Don’t use CQRS, event sourcing, or GraphQL unless your use case truly needs them. Simple CRUD might be sufficient.Poor Separation
Mixing command and query logic in CQRS defeats the purpose. Keep them separate.Missing Documentation
Not documenting message/event formats leads to confusion between teams. Always document your contracts.Security Oversights
Forgetting to secure WebSocket endpoints or GraphQL resolvers. Always implement authentication and authorization.Performance Issues
Not monitoring or profiling advanced features can cause hidden performance issues. Always measure and optimize.10.8 Summary
You’ve mastered advanced patterns in NestJS: Key Concepts:- CQRS: Separate read and write operations
- GraphQL: Flexible query language for APIs
- WebSockets: Real-time bidirectional communication
- Event Sourcing: Store state as sequence of events
- Use advanced patterns only when needed
- Keep code modular and testable
- Document architecture decisions
- Monitor and profile performance
- Start simple, add complexity as needed
- CQRS: Complex domains with read/write separation
- GraphQL: Multiple clients with different data needs
- WebSockets: Real-time communication required
- Event Sourcing: Need full audit trail