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);
}
}
