The Azure Table Storage module for Nest framework (node.js)
npm install @nestjs/azure-database[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
[travis-url]: https://travis-ci.org/nestjs/nest
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
[linux-url]: https://travis-ci.org/nestjs/nest
A progressive Node.js framework for building efficient and scalable server-side applications.
Azure Database (Table Storage, Cosmos DB - NoSQL) module for Nest framework (node.js)
You are reading the documentation for version 3. If you are looking for version 2 documentation, click here. Please also note that version 2 is no longer maintained and will not receive any updates!
For Cosmos DB (NoSQL ONLY)
1. Create a Cosmos DB account and resource (read more)
2. Note down the "URI", Database name and the "Primary Key" (or "Secondary Key") - You will need them later
For Table Storage
1. Create a Storage account and resource (read more)
2. Note down the "Connection string" - You will need it later
``bash`
$ npm i --save @nestjs/azure-database
1. Create or update your existing .env file with the following content:
``
AZURE_COSMOS_DB_NAME=
AZURE_COSMOS_DB_ENDPOINT=
AZURE_COSMOS_DB_KEY=
2. IMPORTANT: Make sure to add your .env file to your .gitignore! The .env file MUST NOT be versioned on Git.
3. Make sure to include the following call to your main.ts file:
`typescript`
if (process.env.NODE_ENV !== 'production') require('dotenv').config();
> This line must be added before any other imports!
> Note: Check out the CosmosDB example project included in the sample folder
#### Prepare your entity
0. Create a new feature module, eg. with the nest CLI:
`shell`
$ nest generate module event
1. Create a Data Transfer Object (DTO) inside a file named event.dto.ts:
`typescript`
export class EventDTO {
id?: string;
name: string;
type: string;
createdAt: Date;
}
2. Create a file called event.entity.ts and describe the entity model using the provided decorators:
- @CosmosPartitionKey(value: string | HierarchicalPartitionKey): Represents the PartitionKey or HierarchicalPartitionKey of the entity (required).
- @CosmosDateTime(value?: string): For DateTime values.
Important: Using a Hierarchical Partition Key requires a container that uses hierarchical partition keys, read more.
For instance, the shape of the following entity:
`typescript
import { CosmosDateTime, CosmosPartitionKey } from '@nestjs/azure-database';
import { PartitionKeyDefinitionVersion, PartitionKeyKind } from '@azure/cosmos';
@CosmosPartitionKey({
paths: ['/name', '/type/label'],
version: PartitionKeyDefinitionVersion.V2,
kind: PartitionKeyKind.MultiHash,
})
export class Event {
id?: string;
name: string;
type: {
label: string;
};
@CosmosDateTime() createdAt: Date;
}
`
Will be automatically converted to:
`json`
{
"name": "NestJS Meetup",
"type": {
"label": "Meetup"
},
"createdAt": "2019-11-15T17:05:25.427Z"
}
1. Import the AzureCosmosDbModule inside your Nest feature module event.module.ts:
`typescript
import { AzureCosmosDbModule } from '@nestjs/azure-database';
import { Module } from '@nestjs/common';
import { Event } from './event.entity';
@Module({
imports: [
AzureCosmosDbModule.forRoot({
dbName: process.env.AZURE_COSMOS_DB_NAME,
endpoint: process.env.AZURE_COSMOS_DB_ENDPOINT,
key: process.env.AZURE_COSMOS_DB_KEY,
retryAttempts: 1,
}),
AzureCosmosDbModule.forFeature([{ dto: Event }]),
],
})
export class EventModule {}
`
#### CRUD operations
0. Create a service that will abstract the CRUD operations:
`shell`
$ nest generate service event
1. Use the @InjectModel(Event) to get an instance of the Azure Cosmos DB Container for the entity definition created earlier:
`typescript
import { InjectModel } from '@nestjs/azure-database';
import type { Container } from '@azure/cosmos';
import { Injectable } from '@nestjs/common';
import { Event } from './event.entity';
@Injectable()
export class EventService {
constructor(
@InjectModel(Event)
private readonly eventContainer: Container,
) {}
}
`
@InjectModel(Event) will inject an Azure Cosmos DB Container instance for the Event entity. The Container provides a list of public methods for managing the database.
IMPORTANT: Please note that the Container instance is not a NestJS repository. It is the actual instance provided by the official Azure Cosmos DB SDK.
##### CREATE
`typescript`
async create(eventDto: EventDTO): Promise
const { resource } = await this.eventContainer.items.create
eventDto,
);
return resource;
}
##### READ
Fetches all the results of the query.
`typescript
async getEvents(): Promise
const querySpec = {
query: 'SELECT * FROM events',
};
const { resources } = await this.eventContainer.items
.query
.fetchAll();
return resources;
}
`
Fetch a single resource.
`typescript`
async getEvent(id: string, partitionKey: string | string[]): Promise
const { resource } = await this.eventContainer
.item(id, type)
.read
return resource;
}
##### UPDATE
Replaces an item in the database.
`typescript
async updateEvent(
id: string,
partitionKey: string | string[],
eventData: EventDTO,
): Promise
let { resource: item } = await this.eventContainer
.item(id, type)
.read
item = {
...item,
...eventData,
};
const { resource: replaced } = await this.eventContainer
.item(id, type)
.replace(item);
return replaced;
}
`
##### DELETE
Deletes an item from the database.
`typescript
async deleteEvent(id: string, partitionKey: string | string[]): Promise
const { resource: deleted } = await this.eventContainer
.item(id, type)
.delete
return deleted;
}
`
#### Hierarchical Partition Keys
If using hierarchical partition keys, you need to provide the partition key as an array of strings when calling one of the CRUD methods on the Container. For example, when reading a single resource:
`javascript`
this.eventContainer
.item("1234", ['foo', 'bar'])
.read
Read more about Hierarchical Partition Keys.
1. Create or update your existing .env file with the following content:
``
AZURE_STORAGE_CONNECTION_STRING=
2. IMPORTANT: Make sure to add your .env file to your .gitignore! The .env file MUST NOT be versioned on Git.
3. Make sure to include the following call to your main.ts file:
`typescript`
if (process.env.NODE_ENV !== 'production') require('dotenv').config();
> This line must be added before any other imports!
4. The AzureTableStorageModule will automatically read the AZURE_STORAGE_CONNECTION_STRING environment variable and use it to connect to your Azure Storage account.
Check out the Table Storage example project included in the sample folder
#### Prepare your entity
0. Create a new feature module, eg. with the nest CLI:
`shell`
$ nest generate module event
1. Create a Data Transfer Object (DTO) inside a file named event.dto.ts:
`typescript`
export class EventDTO {
name: string;
type: string;
}
2. Create a file called event.entity.ts and describe the entity model using plain JavaScript objects. The only requirement is to provide a partitionKey and a rowKey properties. For instance, the shape of the following entity:
`typescript`
export class Event {
partitionKey: string; // required
rowKey: string; // required
name: string;
type: string;
}
1. Import the AzureTableStorageModule inside your Nest feature module event.module.ts:
`typescript
import { Module } from '@nestjs/common';
import { AzureTableStorageModule } from '@nestjs/azure-database';
@Module({
imports: [AzureTableStorageModule.forFeature(Event)],
})
export class EventModule {}
`
You can optionally pass in the following arguments:
`typescript
import { Module } from '@nestjs/common';
import { AzureTableStorageModule } from '@nestjs/azure-database';
@Module({
imports: [
AzureTableStorageModule.forFeature(Event, {
table: 'foobar',
createTableIfNotExists: true,
}),
],
})
export class EventModule {}
`
- table: string: The name of the table. If not provided, the name of the Event entity will be used as a table namecreateTableIfNotExists: boolean
- : Whether to automatically create the table if it doesn't exists or not:true
- If the table will be created during the startup of the app.false
- If the table will not be created. You will have to create the table by yourself before querying it!
#### CRUD operations
0. Create a service that will abstract the CRUD operations:
`shell`
$ nest generate service event
1. Use the @InjectRepository(Event) to get an instance of the Azure Repository for the entity definition created earlier:
`typescript
import { InjectRepository, Repository } from '@nestjs/azure-database';
import { Injectable } from '@nestjs/common';
import { Event } from './event.entity';
@Injectable()
export class EventService {
constructor(
@InjectRepository(Event)
private readonly eventRepository: Repository
) {}
}
`
The AzureTableStorageRepository provides a list of public methods for managing various CRUD operations:
##### CREATE
create(entity: T): Promise: creates a new entity.
`typescript`
async create(event: Event): Promise
return await this.eventRepository.create(event);
}
##### READ
find(partitionKey: string, rowKey: string): Promise: finds one entity using its partitionKey and rowKey.
`typescript`
async find(partitionKey: string, rowKey: string): Promise
return await this.eventRepository.find(partitionKey, rowKey);
}
findAll(options: { queryOptions?: TableEntityQueryOptions }): Promise: finds all entities.
`typescript`
async findAll(options: { queryOptions?: TableEntityQueryOptions }): Promise
return await this.eventRepository.findAll();
}
##### UPDATE
update(partitionKey: string, rowKey: string, entity: T): Promise: Updates an entity using a "merge" strategy.
`typescript`
async update(
partitionKey: string,
rowKey: string,
event: Event,
): Promise
return await this.eventRepository.update(partitionKey, rowKey, event);
}
##### DELETE
delete(partitionKey: string, rowKey: string): Promise: Removes an entity from the table.
`typescript``
async delete(partitionKey: string, rowKey: string): Promise
await this.eventRepository.delete(partitionKey, rowKey);
}
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.
[edm-types]: http://bit.ly/nest-edm