A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.
Azure Database (Table Storage and more) module for Nest framework (node.js)
- Create a Storage account and resource (read more)
- For Table Storage, 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.
$ npm i --save @nestjs/azure-database
- Create or update your existing
.env
file with the following content:
AZURE_STORAGE_CONNECTION_STRING=
-
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!
- Create a new feature module, eg. with the nest CLI:
$ nest generate module contact
- Create a Data Transfert Object (DTO) inside a file named
contact.dto.ts
:
export class ContactDTO {
name: string;
message: string;
}
- Create a file called
contact.entity.ts
and describe the entity model using the provided decorators:
@EntityPartitionKey(value: string)
: Represents the PartitionKey
of the entity (required).
@EntityRowKey(value: string)
: Represents the RowKey
of the entity (required).
@EntityInt32(value?: string)
: For signed 32-bit integer values.
@EntityInt64(value?: string)
: For signed 64-bit integer values.
@EntityBinary(value?: string)
: For binary (blob) data.
@EntityBoolean(value?: string)
: For true
or false
values.
@EntityString(value?: string)
: For character data.
@EntityDouble(value?: string)
: For floating point numbers with 15 digit precision.
@EntityDateTime(value?: string)
: For time of day.
For instance, the shape of the following entity:
import { EntityPartitionKey, EntityRowKey, EntityString } from '@nestjs/azure-database';
@EntityPartitionKey('ContactID')
@EntityRowKey('ContactName')
export class Contact {
@EntityString() name: string;
@EntityString() message: string;
}
Will be automatically converted to:
{
"PartitionKey": { "_": "ContactID", "$": "Edm.String" },
"RowKey": { "_": "ContactName", "$": "Edm.String" },
"name": { "_": undefined, "$": "Edm.String" },
"message": { "_": undefined, "$": "Edm.String" }
}
- Import the
AzureTableStorageModule
inside your Nest feature modulecontact.module.ts
:
import { Module } from '@nestjs/common';
import { AzureTableStorageModule } from '@nestjs/azure-database';
import { ContactController } from './contact.controller';
import { ContactService } from './contact.service';
import { Contact } from './contact.entity';
@Module({
imports: [AzureTableStorageModule.forFeature(Contact)],
providers: [ContactService],
controllers: [ContactController],
})
export class ContactModule {}
You can optionnaly pass in the following arguments:
AzureTableStorageModule.forFeature(Contact, {
table: 'AnotherTableName',
createTableIfNotExists: true,
})
table: string
: The name of the table. If not provided, the name of theContact
entity will be used as a table namecreateTableIfNotExists: boolean
: Whether to automatically create the table if it doesn't exists or not:- If
true
the table will be created during the startup of the app. - If
false
the table will not be created. You will have to create the table by yoursel before querying it!
- If
- Create a service that will abstract the CRUD operations:
$ nest generate service contact
- Import the
AzureTableStorageRepository
and provide it with the entity definition created earlier:
import { Injectable } from '@nestjs/common';
import { Repository, InjectRepository } from '@nestjs/azure-database';
import { Contact } from './contact.entity';
@Injectable()
export class ContactService {
constructor(
@InjectRepository(Contact)
private readonly contactRepository: Repository<Contact>) {}
}
The AzureTableStorageRepository
provides a couple of public APIs and Interfaces for managing various CRUD operations:
create(entity: T): Promise<T>
: creates a new entity.
@Get()
async getAllContacts() {
return await this.contactService.findAll();
}
find(rowKey: string, entity: Partial<T>): Promise<T>
: finds one entity using its RowKey
.
@Get(':rowKey')
async getContact(@Param('rowKey') rowKey) {
try {
return await this.contactService.find(rowKey, new ContactEntity());
} catch (error) {
// Entity not found
throw new UnprocessableEntityException(error);
}
}
findAll(tableQuery?: azure.TableQuery, currentToken?: azure.TableService.TableContinuationToken): Promise<AzureTableStorageResultList<T>>
: finds all entities that matche the given query (return all entities if no query provided).
@Get()
async getAllContacts() {
return await this.contactService.findAll();
}
update(rowKey: string, entity: Partial<T>): Promise<T>
: Updates an entity. It does a partial update.
@Put(':rowKey')
async saveContact(@Param('rowKey') rowKey, @Body() contactData: ContactDTO) {
try {
const contactEntity = new ContactEntity();
// Disclaimer: Assign only the properties you are expecting!
Object.assign(contactEntity, contactData);
return await this.contactService.update(rowKey, contactEntity);
} catch (error) {
throw new UnprocessableEntityException(error);
}
}
@Patch(':rowKey')
async updateContactDetails(@Param('rowKey') rowKey, @Body() contactData: Partial<ContactDTO>) {
try {
const contactEntity = new ContactEntity();
// Disclaimer: Assign only the properties you are expecting!
Object.assign(contactEntity, contactData);
return await this.contactService.update(rowKey, contactEntity);
} catch (error) {
throw new UnprocessableEntityException(error);
}
}
delete(rowKey: string, entity: T): Promise<AzureTableStorageResponse>
: Removes an entity from the database.
@Delete(':rowKey')
async deleteDelete(@Param('rowKey') rowKey) {
try {
const response = await this.contactService.delete(rowKey, new ContactEntity());
if (response.statusCode === 204) {
return null;
} else {
throw new UnprocessableEntityException(response);
}
} catch (error) {
throw new UnprocessableEntityException(error);
}
}
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.