ɳSelfɳSELFDOCS
  • Getting Started

    • Introduction
    • Quick Start
    • Installation
    • Your First Project
  • Core Concepts

    • Architecture Overview
    • Project Structure
    • Configuration
    • Environments
  • Services

    • PostgreSQL Database
    • Hasura GraphQL
    • Authentication
    • Real-Time Communication
    • Storage (MinIO)
    • Email Configuration
    • Redis Cache
    • Search Engines
    • Functions
    • MLflow (ML Tracking)
    • Monitoring & Metrics
    • Admin UI
    • Dashboard
  • Database Tools

    • Schema Management
    • Migrations
    • Seeding Data
    • Backup & Restore
    • dbdiagram.io Sync
  • Microservices

    • NestJS Services
    • BullMQ Workers
    • Go Services
    • Python Services
  • CLI Reference

    • Complete Command Reference
    • Core Commands
    • Database Commands
    • Service Management
    • Production Commands
  • Deployment

    • Local Development
    • Production Setup
    • SSL/TLS Configuration
    • Domain Configuration
    • Environment Variables
  • Advanced Topics

    • Multi-Tenancy & SaaS
    • Security & Hardening
    • Custom Actions
    • Webhooks
    • Performance Tuning
    • Troubleshooting
  • Migration Guides

    • From Supabase
    • From Nhost
    • From Firebase
  • Resources

    • Changelog
    • Licensing
    • FAQ
    • Contributing
    • Support

NestJS Microservices

v0.4.8

Updated for ɳSelf v0.4.8


ɳSelf provides comprehensive support for NestJS microservices through custom service templates, enabling you to build scalable, modular backend services that integrate seamlessly with your ɳSelf stack. With the nest-js and nest-ts templates, automatic configuration, and production-ready deployment, you can focus on building features while ɳSelf handles the infrastructure.

Overview

NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. When combined with ɳSelf, you get:

Key Benefits

  • Rapid Development: Pre-configured nest-js and nest-ts templates
  • Seamless Integration: Automatic connection to PostgreSQL, Redis, and other ɳSelf services
  • Microservices Architecture: Built-in support for distributed systems patterns
  • Type Safety: Full TypeScript support with shared types
  • Production Ready: Docker containers, health checks, and monitoring

Supported Patterns

  • REST APIs: Traditional HTTP-based services
  • GraphQL APIs: Integration with Hasura or standalone
  • Message Queues: Integration with BullMQ and Redis
  • Microservices: Inter-service communication patterns
  • CRON Jobs: Scheduled tasks and background processing

Getting Started

Custom Service Configuration

Add NestJS services using the custom service (CS_N) format in your .env file:

# Custom Service Format: CS_N=name:template:port:route
# Available NestJS templates: nest-js, nest-ts

# NestJS API with TypeScript (recommended)
CS_1=api:nest-ts:3001:/api

# NestJS webhook handler
CS_2=webhooks:nest-ts:3002:/webhooks

# NestJS auth microservice
CS_3=auth-service:nest-ts:3003:/auth

Generate Service Structure

# Generate NestJS services from templates
nself build

# Start all services
nself start

This creates the following structure:

services/
├── api/                     # Main API service (nest-ts)
│   ├── src/
│   ├── Dockerfile
│   ├── package.json
│   └── tsconfig.json
├── webhooks/               # Webhook handler service (nest-ts)
│   ├── src/
│   ├── Dockerfile
│   └── package.json
└── auth-service/           # Authentication microservice (nest-ts)
    ├── src/
    ├── Dockerfile
    └── package.json

Service Templates

REST API Service

Basic REST API with database integration:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    ConfigModule.forRoot(),
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: process.env.POSTGRES_HOST,
      port: parseInt(process.env.POSTGRES_PORT),
      username: process.env.POSTGRES_USER,
      password: process.env.POSTGRES_PASSWORD,
      database: process.env.POSTGRES_DB,
      autoLoadEntities: true,
      synchronize: false, // Use ɳSelf migrations instead
    }),
    UsersModule,
  ],
})
export class AppModule {}

GraphQL Integration

Integration with Hasura GraphQL:

// src/graphql/graphql.module.ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriverConfig, ApolloDriver } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql',
      context: ({ req }) => ({ req }),
      introspection: true,
      playground: true,
    }),
  ],
})
export class GraphQLAppModule {}

Message Queue Integration

BullMQ integration for background jobs:

// src/jobs/jobs.module.ts
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { EmailProcessor } from './processors/email.processor';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: process.env.REDIS_HOST,
        port: parseInt(process.env.REDIS_PORT),
      },
    }),
    BullModule.registerQueue({
      name: 'email',
    }),
  ],
  providers: [EmailProcessor],
})
export class JobsModule {}

Database Integration

TypeORM Configuration

Pre-configured TypeORM setup with ɳSelf database:

// src/database/database.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        type: 'postgres',
        host: config.get('POSTGRES_HOST'),
        port: config.get('POSTGRES_PORT'),
        username: config.get('POSTGRES_USER'),
        password: config.get('POSTGRES_PASSWORD'),
        database: config.get('POSTGRES_DB'),
        entities: [__dirname + '/../**/*.entity{.ts,.js}'],
        synchronize: false,
        logging: config.get('NODE_ENV') === 'development',
        ssl: config.get('NODE_ENV') === 'production' ? { rejectUnauthorized: false } : false,
      }),
    }),
  ],
})
export class DatabaseModule {}

Entity Example

// src/users/entities/user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password_hash: string;

  @Column({ nullable: true })
  first_name: string;

  @Column({ nullable: true })
  last_name: string;

  @Column({ default: true })
  is_active: boolean;

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;
}

Advanced Features

Authentication Integration

JWT authentication with ɳSelf's auth service:

// src/auth/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const token = request.headers.authorization?.split(' ')[1];
    
    if (!token) return false;
    
    try {
      const payload = this.jwtService.verify(token);
      request.user = payload;
      return true;
    } catch {
      return false;
    }
  }
}

Health Checks

Automatic health check endpoints:

// src/health/health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HealthCheck, TypeOrmHealthIndicator } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}

Logging and Monitoring

// src/common/interceptors/logging.interceptor.ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  private readonly logger = new Logger(LoggingInterceptor.name);

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const method = request.method;
    const url = request.url;
    const now = Date.now();

    return next.handle().pipe(
      tap(() => {
        const response = context.switchToHttp().getResponse();
        const statusCode = response.statusCode;
        const delay = Date.now() - now;
        
        this.logger.log(`${method} ${url} ${statusCode} - ${delay}ms`);
      }),
    );
  }
}

Deployment and Scaling

Docker Configuration

Each NestJS service gets optimized Docker configuration:

# Dockerfile (auto-generated)
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

FROM node:18-alpine AS runtime
WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nestjs -u 1001

# Copy built application
COPY --from=builder --chown=nestjs:nodejs /app/node_modules ./node_modules
COPY --chown=nestjs:nodejs . .

USER nestjs
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

CMD ["npm", "run", "start:prod"]

Horizontal Scaling

# Scale services using multiple CS_N entries
CS_1=api-1:nest-ts:3001:/api
CS_2=api-2:nest-ts:3002:/api
CS_3=api-3:nest-ts:3003:/api

# Or use Docker Compose deploy configuration
# Configure in .env and rebuild
nself build && nself restart

CLI Commands

Service Management

# Add a NestJS service via CS_N configuration
# In .env file:
CS_1=user-service:nest-ts:3001:/users

# Rebuild to generate from template
nself build

# Start services
nself start

Development Tools

# View service logs
nself logs api

# Follow logs in real-time
nself logs api -f

# Execute commands in service container
nself exec api npm run migration:generate

# Check service status
nself status

Best Practices

Architecture Patterns

  • Single Responsibility: Each service handles one domain
  • Database Per Service: Use schema separation or separate databases
  • API Gateway Pattern: Use one service as the main API gateway
  • Event-Driven Communication: Use BullMQ for async service communication

Development Workflow

  1. Schema First: Design your database schema first
  2. Generate Entities: Create TypeORM entities from schema
  3. Build Services: Implement business logic in services
  4. Add Controllers: Create API endpoints
  5. Write Tests: Add unit and integration tests
  6. Deploy: Use ɳSelf for production deployment

Next Steps

Now that you understand NestJS microservices:

  • BullMQ Workers - Add background job processing
  • Database Management - Schema and migration management
  • Production Deployment - Deploy your services
  • Monitoring & Logs - Monitor your microservices

NestJS services provide a robust, scalable foundation for building enterprise-grade applications with nself.