logo

NestPlatform Open Source library


I. Overview

NestPlatform is an open-source collection of Spring-inspired infrastructure libraries for NestJS. It focuses on reusable backend capabilities that commonly appear across enterprise applications: transaction management, declarative caching, Redis integration, declarative HTTP clients, and distributed locks.

The ecosystem follows the same philosophy as the Spring Framework: move repetitive infrastructure concerns into declarative decorators and reusable modules, while keeping business services clean and expressive.

1. Package ecosystem

| Package | Purpose | | --- | --- | | @nestplatform/common | Shared utilities and decorators used across the ecosystem. | | @nestplatform/transactional | ORM-agnostic transaction management module inspired by Spring @Transactional. | | @nestplatform/transactional-typeorm | TypeORM transaction adapter for @nestplatform/transactional. | | @nestplatform/transactional-mongoose | Mongoose transaction adapter for @nestplatform/transactional. | | @nestplatform/cacheable | Spring-like declarative caching decorators for NestJS. | | @nestplatform/feign | Declarative HTTP client library inspired by OpenFeign. | | @nestplatform/redis | Redis integration utilities for NestJS. | | @nestplatform/distribution-lock | Distributed lock abstraction for NestJS. | | @nestplatform/distribution-redlock | Redis Redlock adapter for distributed locks. | | @nestplatform/distribution-postgres-advisory-lock | PostgreSQL advisory lock adapter for distributed locks. |

2. Design goals

  • Declarative first: Use decorators to describe infrastructure behavior close to business methods.
  • ORM-agnostic core: Keep transactional abstractions independent from a specific persistence library.
  • Adapter-based architecture: Plug in TypeORM, Mongoose, Redis Redlock, or Postgres advisory lock support as needed.
  • NestJS native: Integrate through modules, providers, dependency injection, and decorators.
  • Enterprise-focused: Reduce repeated boilerplate in finance, ERP, banking, IoT, and distributed systems.

3. Key capabilities

  • Transaction orchestration: Apply transaction boundaries at method level with Spring-like semantics.
  • Declarative caching: Cache method results using decorators rather than repeated cache-manager code.
  • Distributed locks: Protect critical sections across multiple instances.
  • Redis integration: Centralize Redis setup and reuse it across modules.
  • Declarative HTTP clients: Describe remote API clients as interfaces/classes and let the library handle request execution.

4. Tech stack


II. Getting Started

Prerequisites

NestPlatform libraries are built for:

  • Framework: NestJS >=9.0.0
  • Database ORMs: TypeORM or Mongoose (optional, for transactions)
  • Locking: Redis (for Redlock) or PostgreSQL (for advisory locks)

III. Core Modules & Usage

Here is how to set up and use the most popular packages from the NestPlatform collection.

1. Declarative Transactions (@nestplatform/transactional)

Manage database transactions declaratively. Supports propagation, isolation levels, and read-only flags.

Installation:

# Core package
npm install @nestplatform/transactional

# Adapter (TypeORM or Mongoose)
npm install @nestplatform/transactional-typeorm

Import Module:

Initialize the transaction context manager and ORM adapter in your app module.

/* app.module.ts */
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TransactionalModule } from '@nestplatform/transactional';
import { typeOrmTransactionAdapter } from '@nestplatform/transactional-typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      /* TypeORM options */
    }),
    TransactionalModule.forRoot({
      adapter: typeOrmTransactionAdapter,
    }),
  ],
})
export class AppModule {}

Usage:

Apply the @Transactional() decorator to any provider method. The method will run inside a transaction. If it throws an error, the transaction rolls back; if it returns successfully, the transaction commits.

/* user.service.ts */
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Transactional } from '@nestplatform/transactional';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  @Transactional()
  async createUser(data: Partial<User>) {
    const user = this.userRepository.create(data);
    await this.userRepository.save(user);
    // Any nested repository calls here share the same transaction
    return user;
  }
}

2. Declarative Caching (@nestplatform/cacheable)

Cache method results declaratively with dynamic cache key building.

Installation:

npm install @nestplatform/cacheable

Import Module:

/* app.module.ts */
import { Module } from '@nestjs/common';
import { CacheableModule } from '@nestplatform/cacheable';

@Module({
  imports: [
    CacheableModule.forRoot({
      store: 'redis',
      host: 'localhost',
      port: 6379,
    }),
  ],
})
export class AppModule {}

Usage:

Decorate methods with @Cacheable(). Use expressions or resolver functions to evaluate keys from arguments.

/* product.service.ts */
import { Injectable } from '@nestjs/common';
import { Cacheable, CacheEvict } from '@nestplatform/cacheable';

@Injectable()
export class ProductService {
  @Cacheable({
    cacheName: 'products',
    key: '#id', // Dynamic key resolution based on arguments
    ttl: 3600,  // Cache TTL in seconds
  })
  async getProductById(id: string) {
    // Heavy DB query
    return this.productRepository.findOne(id);
  }

  @CacheEvict({
    cacheName: 'products',
    key: '#id',
  })
  async updateProduct(id: string, updateData: any) {
    await this.productRepository.update(id, updateData);
  }
}

3. Distributed Locking (@nestplatform/distribution-lock)

Coordinate operations across multiple running instances using centralized locks.

Installation:

npm install @nestplatform/distribution-lock
npm install @nestplatform/distribution-redlock

Import Module:

/* app.module.ts */
import { Module } from '@nestjs/common';
import { DistributionLockModule } from '@nestplatform/distribution-lock';
import { redlockAdapter } from '@nestplatform/distribution-redlock';

@Module({
  imports: [
    DistributionLockModule.forRoot({
      adapter: redlockAdapter({
        host: 'localhost',
        port: 6379,
      }),
    }),
  ],
})
export class AppModule {}

Usage:

/* payment.service.ts */
import { Injectable } from '@nestjs/common';
import { DistributionLock } from '@nestplatform/distribution-lock';

@Injectable()
export class PaymentService {
  @DistributionLock({
    name: 'process-invoice',
    key: '#invoiceId',
    ttl: 10000, // Lock expiry in milliseconds
  })
  async processInvoice(invoiceId: string) {
    // This code block runs exclusively for this invoiceId across all server instances
    await this.chargeCustomer(invoiceId);
  }
}