AWS SDK Javascript V3 dynamic module for NestJS
Let's build a S3 client and inject it into the nest app.
npm install aws-sdk-v3-nest @aws-sdk/client-s3
- Register the module with a S3 Client, in
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AwsSdkModule } from 'aws-sdk-v3-nest';
import { S3Client } from '@aws-sdk/client-s3';
@Module({
imports: [
// register S3 client
AwsSdkModule.register({
client: new S3Client({
region: 'us-west-2',
}),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- use the S3 client in
app.controller.ts
import { ListBucketsCommand, S3Client } from '@aws-sdk/client-s3';
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { InjectAws } from 'aws-sdk-v3-nest';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
// inject the client
@InjectAws(S3Client) private readonly s3: S3Client
) {}
@Get()
async helloAws() {
const listCommand = new ListBucketsCommand({});
const res = await this.s3.send(listCommand);
return res;
}
}
- done!
- Add
aws-sdk-v3-nest
to your projectnpm install aws-sdk-v3-nest
- Make sure at least one AWS SDK for JavaScript V3 is in your project. Please skip this step if you already have it installed
npm install @aws-sdk/client-s3
You can register any AWS SDK client you want. As long as it's a AWS SDK V3 client
A good example: S3Client
import { S3Client } from '@aws-sdk/client-s3';
import { AwsSdkModule } from 'aws-sdk-v3-nest';
// ... your code ...
AwsSdkModule.register({
client: new S3Client({
region: 'us-west-2',
}),
});
The library provides an async useFactory
that allows you to add more logics before setting up the client instance.
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';
import { AwsSdkModule } from 'aws-sdk-v3-nest';
//... your code ...
AwsSdkModule.registerAsync({
clientType: S3Client,
useFactory: async () => {
const s3 = new S3Client({
region: 'us-west-2',
});
try {
const listCommand = new ListBucketsCommand({});
const res = await s3.send(listCommand);
console.log('Connected to S3');
} catch (e) {
console.log('Unable to connect to S3', e);
}
return s3;
},
});
With a registered S3 client, you can now inject the instance to your service and controller.
Make sure the
Client
is the type you registered in module.
/** Use S3 client in AppController */
import { ListBucketsCommand, S3Client } from '@aws-sdk/client-s3';
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { InjectAws } from 'aws-sdk-v3-nest';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
@InjectAws(S3Client) private readonly s3: S3Client,
) {}
@Get()
async helloAws() {
const listCommand = new ListBucketsCommand({});
const res = await this.s3.send(listCommand);
return res;
}
}
To add more instances is easy, just register
more!
If you have same type of clients, please use the key
attribute as the identifier.
Example for multiple S3 client instances
AwsSdkModule.register({
// register the S3 Client with key `US-WEST-2-CLIENT`
key: 'US-WEST-2-CLIENT',
client: new S3Client({
region: 'us-west-2',
}),
}),
AwsSdkModule.register({
// register the S3 Client with key `US-EAST-1-CLIENT`
key: 'US-EAST-1-CLIENT',
client: new S3Client({
region: 'us-east-1',
}),
}),
@InjectAws(S3Client, "US-WEST-2-CLIENT") private readonly s3west2: S3Client,
@InjectAws(S3Client, "US-EAST-1-CLIENT") private readonly s3east1: S3Client,
By default, a client is only available at where it is registered.
You have an option to make it global, isGlobal: true
AwsSdkModule.register({
isGlobal: true,
client: new S3Client({
region: 'us-west-2',
}),
});
If you need a client key for testing purpose. Please pass the AWS SDK V3 client and key
to getClientToken
getClientToken(S3Client, key = "")
Inspired by: nest-aws-sdk