Handling duplicate requests in APIs, especially in payment systems, is a headache. NestJS RedisX offers a neat way to tackle this with its Idempotency Plugin. Let’s dig into how you can set this up.
Getting Started with Idempotency
First things first, install the necessary packages. You'll need both the core and idempotency packages of NestJS RedisX:
npm install @nestjs-redisx/core @nestjs-redisx/idempotency
Configuring the Module
To make the Idempotency Plugin work its magic, you need to configure it in your main module. This setup ensures that the plugin is ready to catch any duplicate requests globally.
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RedisModule } from '@nestjs-redisx/core';
import { IdempotencyPlugin } from '@nestjs-redisx/idempotency';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { IdempotencyInterceptor } from '@nestjs-redisx/idempotency';
@Module({
imports: [
ConfigModule.forRoot(),
RedisModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
plugins: [
IdempotencyPlugin.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
defaultTtl: 86400, // 24 hours
headerName: 'Idempotency-Key',
}),
}),
],
useFactory: (config: ConfigService) => ({
clients: {
host: config.get('REDIS_HOST', 'localhost'),
port: config.get('REDIS_PORT', 6379),
},
}),
}),
],
providers: [
{ provide: APP_INTERCEPTOR, useClass: IdempotencyInterceptor },
],
})
export class AppModule {}
Decorating Your Endpoints
Once your module is good to go, use the @Idempotent decorator on your endpoints. This ensures that each request is uniquely processed based on the Idempotency-Key.
import { Controller, Post, Body } from '@nestjs/common';
import { Idempotent } from '@nestjs-redisx/idempotency';
@Controller('payments')
export class PaymentsController {
constructor(private readonly paymentService: PaymentService) {}
@Post()
@Idempotent()
async createPayment(@Body() dto: CreatePaymentDto) {
return this.paymentService.process(dto);
}
}
Behind the Scenes
Here’s the lowdown: the Idempotency Plugin checks each request’s Idempotency-Key. If it’s seen the key before, it serves the cached result. No re-processing, no fuss.
- Body Fingerprinting: It goes a step further by ensuring the request body’s fingerprint matches the key. This prevents using the same key for different data.
- Concurrent Handling: If multiple requests with the same key pop up, the plugin handles them in sequence, avoiding any duplication.
Incorporating an idempotency layer using NestJS RedisX is pretty straightforward. It's a solid way to dodge duplicate processing in sensitive areas like payments. Want to dive deeper? Check out the official documentation.
Top comments (0)