A progressive Node.js framework for building efficient and scalable server-side applications.
Azure Storage module for Nest framework (node.js)
Learn how to get started with Azure table storage for NestJS
- Create a Storage account and resource (read more)
- In the Azure Portal, go to Dashboard > Storage > your-storage-account.
- Note down the "AccountName", "AccountKey" obtained at Access keys and "AccountSAS" from Shared access signature under Settings tab.
- (Optional) Install the azurite package to setup a development environment.
Using the Nest CLI:
$ nest add @nestjs/azure-storage
You can pass additional flags to customize the post-install schematic. For example, if your base application directory is different than src
, use --rootDir
flag:
$ nest add @nestjs/azure-storage --rootDir app
When requested, provide the storageAccountName
and storageAccountSAS
(see below).
Other available flags:
rootDir
- Application root directory, default:src
rootModuleFileName
- the name of the root module file, default:app.module
rootModuleClassName
- the name of the root module class, default:AppModule
mainFileName
- Application main file, default:main
skipInstall
- skip installing dependencies, default:false
serviceUrlProvider
- override the default service url provider (which is pointing tohttps://${options.accountName}.blob.core.windows.net/?${options.sasKey}
)storageAccountName
(required) - The Azure Storage account name (see: http://bit.ly/azure-storage-account)storageAccountSAS
(required) - The Azure Storage SAS Key (see: http://bit.ly/azure-storage-sas-key).
- Install the package using NPM:
$ npm i -S @nestjs/azure-storage
- Create or update your existing
.env
file with the following content:
# See: http://bit.ly/azure-storage-sas-key
AZURE_STORAGE_SAS_KEY=
# See: http://bit.ly/azure-storage-account
AZURE_STORAGE_ACCOUNT=
The SAS has the following format:
?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-12-31T22:54:03Z&st=2019-07-11T13:54:03Z&spr=https,http&sig=WmAl%236251oj11biPK2xcpLs254152H9s0%3D
-
IMPORTANT: Make sure to add your
.env
file to your.gitignore
! The.env
file MUST NOT be versionned on Git. -
Make sure to include the following call to your main file:
if (process.env.NODE_ENV !== 'production') require('dotenv').config();
This line must be added before any other imports!
- Import the
AzureStorageModule
with the following configuration:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AzureStorageModule } from '@nestjs/azure-storage';
@Module({
controllers: [AppController],
providers: [AppService],
imports: [
AzureStorageModule.withConfig({
sasKey: process.env['AZURE_STORAGE_SAS_KEY'],
accountName: process.env['AZURE_STORAGE_ACCOUNT'],
containerName: 'nest-demo-container',
}),
],
})
export class AppModule {}
If you want to use asynchronous configuration options using factory or class,
const storageConfigFactory = async () => {
sasKey: process.env['AZURE_STORAGE_SAS_KEY'],
accountName: process.env['AZURE_STORAGE_ACCOUNT'],
containerName: 'nest-demo-container',
};
@Module({
controllers: [AppController],
providers: [AppService],
imports: [
AzureStorageModule.withConfigAsync({
useFactory: storageConfigFactory,
}),
],
})
export class AppModule {}
You may provide a default
containerName
name for the whole module, this will apply to all controllers withing this module. You can also provide (override) thecontainerName
in the controller, for each route.
import {
Controller,
Logger,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
AzureStorageFileInterceptor,
UploadedFileMetadata,
} from '@nestjs/azure-storage';
@Controller()
export class AppController {
@Post('azure/upload')
@UseInterceptors(
AzureStorageFileInterceptor('file'),
)
UploadedFilesUsingInterceptor(
@UploadedFile()
file: UploadedFileMetadata,
) {
Logger.log(`Storage URL: ${file.storageUrl}`, 'AppController');
}
}
import {
Controller,
Logger,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
AzureStorageFileInterceptor,
UploadedFileMetadata,
} from '@nestjs/azure-storage';
@Controller()
export class AppController {
@Post('azure/upload')
@UseInterceptors(
AzureStorageFileInterceptor('file', null, {
containerName: 'nest-demo-container-interceptor',
}),
)
UploadedFilesUsingInterceptor(
@UploadedFile()
file: UploadedFileMetadata,
) {
Logger.log(`Storage URL: ${file.storageUrl}`, 'AppController');
}
}
import {
Controller,
Logger,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
AzureStorageFileInterceptor,
AzureStorageService,
UploadedFileMetadata,
} from '@nestjs/azure-storage';
@Controller()
export class AppController {
constructor(private readonly azureStorage: AzureStorageService) {}
@Post('azure/upload')
@UseInterceptors(FileInterceptor('file'))
async UploadedFilesUsingService(
@UploadedFile()
file: UploadedFileMetadata,
) {
file = {
...file,
originalname: 'foo-bar.txt',
};
const storageUrl = await this.azureStorage.upload(file);
Logger.log(`Storage URL: ${storageUrl}`, 'AppController');
}
}
import { AzureStorageService } from '@nestjs/azure-storage';
import { Injectable } from '@nestjs/common';
@Injectable()
export class TestService {
constructor(
readonly storage: AzureStorageService
) {
storage.getContainerClient().getBlobClient(file.originalname).downloadToBuffer().then(buffer => {
buffer.toString() // content of foo-bar.txt
});
}
}
You can setup a development environment using the default configuration from azurite. This example also shows you how to use the library with a AccountKEY instead of SAS configuration, this is not recommended for production.
import {
SASProtocol,
StorageSharedKeyCredential,
generateAccountSASQueryParameters,
AccountSASResourceTypes,
AccountSASServices,
AccountSASPermissions
} from "@azure/storage-blob";
import {Module} from "@nestjs/common";
import {AzureStorageModule} from "@nestjs/azure-storage";
@Module({
imports: [
AzureStorageModule.withConfig({
containerName: "container",
accountName: "devstoreaccount1",
serviceUrlProvider: (options) => {
return `http://127.0.0.1:10000/${options.accountName}/?${options.sasKey}`
},
sasKey: generateAccountSASQueryParameters({
resourceTypes: AccountSASResourceTypes.parse("sco").toString(),
services: AccountSASServices.parse("b").toString(),
permissions: AccountSASPermissions.parse("racwdl"),
startsOn: new Date(Date.now() - 86400),
expiresOn: new Date(Date.now() + 86400),
protocol: SASProtocol.HttpsAndHttp
}, new StorageSharedKeyCredential(...Object.values({
accountName: 'devstoreaccount1',
accountKey: 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='
}) as [string, string])).toString(),
})
]
})
export class AppModule {
}
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
- Author - Wassim Chegham
- Website - https://wassim.dev
- Twitter - @manekinekko
Nest is MIT licensed.