NestJS Minio Client
The `nestjs-minio-client` package provides a robust integration of the Minio S3-compatible object storage client into the NestJS framework. It offers a `MinioModule` for streamlined configuration and registration, supporting both synchronous `register()` and asynchronous `registerAsync()` methods, which is particularly useful for injecting configuration from NestJS's `@nestjs/config` package. An injectable `MinioService` then provides direct access to the underlying Minio JS SDK client instance, allowing developers to interact with Minio's API. The current stable version is 2.2.0, with a consistent release cadence focusing on updates to dependencies, NestJS compatibility, and internal refactoring. It serves as a dedicated wrapper, simplifying Minio usage within NestJS applications and abstracting away direct SDK initialization. It requires NestJS version 9 or later.
Common errors
-
TypeError: MinioModule.register is not a function
cause Attempting to use `MinioModule.register` or `registerAsync` without correctly importing `MinioModule` or due to module resolution issues.fixEnsure `import { MinioModule } from 'nestjs-minio-client';` is present at the top of your module file (e.g., `app.module.ts`). Verify `nestjs-minio-client` is correctly installed in `node_modules`. -
Nest can't resolve dependencies of the MinioService (?). Please make sure that the argument ConfigService at index [0] is available in the MinioModule context.
cause This error typically occurs when `MinioModule.registerAsync` is used with `inject: [ConfigService]` but `ConfigModule` is not imported within the `MinioModule`'s imports array.fixWhen using `MinioModule.registerAsync` with `ConfigService`, ensure `imports: [ConfigModule]` is included in the `MinioModule.registerAsync` options object, and `ConfigModule.forRoot()` or `ConfigModule.forFeature()` is set up correctly in your application's root module. -
Error: Minio configuration missing 'endPoint', 'port', 'accessKey', or 'secretKey'.
cause The `MinioModule` was registered with incomplete or invalid configuration options.fixReview the configuration object passed to `MinioModule.register()` or returned by `useFactory` in `MinioModule.registerAsync()`. Ensure `endPoint`, `port`, `accessKey`, and `secretKey` are all provided and correctly formatted.
Warnings
- breaking Version 2.0.0 introduced a refactoring to utilize NestJS's configurable module builder. While the `register()` and `registerAsync()` methods remain, internal implementation details and possibly configuration interfaces were updated.
- gotcha The `global` option, introduced in v1.2.0, allows registering the `MinioModule` in the global namespace. While convenient for smaller applications, using global modules can obscure dependencies and complicate testing in larger NestJS projects. It's generally recommended to import modules explicitly where needed.
- breaking This package has a peer dependency on NestJS version 9.0.0 or later. Using it with older NestJS versions may lead to dependency resolution issues or runtime errors due to API incompatibilities.
- gotcha The `MinioService` exposes the raw Minio Javascript SDK client via `minioService.client`. Direct interaction with this client requires familiarity with the underlying Minio SDK's API and error handling mechanisms. Ensure proper error handling and async/await usage when calling SDK methods.
Install
-
npm install nestjs-minio-client -
yarn add nestjs-minio-client -
pnpm add nestjs-minio-client
Imports
- MinioModule
const { MinioModule } = require('nestjs-minio-client');import { MinioModule } from 'nestjs-minio-client'; - MinioService
const { MinioService } = require('nestjs-minio-client');import { MinioService } from 'nestjs-minio-client'; - MinioModule.register
MinioModule.register({ /* options */ }) - MinioModule.registerAsync
MinioModule.registerAsync({ useFactory: ..., inject: [...] })
Quickstart
import { Module } from '@nestjs/common';
import { MinioModule } from 'nestjs-minio-client';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MinioClientService } from './minio-client.service'; // Assuming you have a service using MinioService
@Module({
imports: [
ConfigModule.forRoot(), // Load environment variables
MinioModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => {
return {
endPoint: config.get<string>('MINIO_ENDPOINT') ?? '127.0.0.1',
port: parseInt(config.get<string>('MINIO_PORT') ?? '9000', 10),
useSSL: config.get<string>('MINIO_USE_SSL') === 'true',
accessKey: config.get<string>('MINIO_ACCESS_KEY') ?? process.env.MINIO_ACCESS_KEY ?? '',
secretKey: config.get<string>('MINIO_SECRET_KEY') ?? process.env.MINIO_SECRET_KEY ?? ''
};
},
}),
],
providers: [MinioClientService],
exports: [MinioClientService],
})
export class AppModule {}
// Example minio-client.service.ts
import { Injectable } from '@nestjs/common';
import { MinioService } from 'nestjs-minio-client';
@Injectable()
export class MinioClientService {
constructor(private readonly minioService: MinioService) {}
async listAllBuckets() {
return this.minioService.client.listBuckets();
}
// Add more methods for Minio operations here
async uploadFile(bucketName: string, objectName: string, filepath: string) {
// This is an example, actual Minio client usage would vary
// For instance, you might use putObject, fPutObject, etc.
console.log(`Uploading ${filepath} to ${bucketName}/${objectName}`);
// await this.minioService.client.fPutObject(bucketName, objectName, filepath);
return { success: true, objectName };
}
}