• Stars
    star
    105
  • Rank 328,196 (Top 7 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Azure CosmosDB Database module for Nest framework (node.js) ☁️

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads Coverage Discord Backers on Open Collective Sponsors on Open Collective

Description

Azure Database (Table Storage, Cosmos DB - NoSQL) module for Nest framework (node.js)

Disclaimer

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!

Before Installation

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

Installation

$ npm i --save @nestjs/azure-database

Usage

For Azure Cosmos DB support

  1. Create or update your existing .env file with the following content:
AZURE_COSMOS_DB_NAME=
AZURE_COSMOS_DB_ENDPOINT=
AZURE_COSMOS_DB_KEY=
  1. IMPORTANT: Make sure to add your .env file to your .gitignore! The .env file MUST NOT be versioned on Git.

  2. Make sure to include the following call to your main.ts file:

if (process.env.NODE_ENV !== 'production') require('dotenv').config();

This line must be added before any other imports!

Example

Note: Check out the CosmosDB example project included in the sample folder

Prepare your entity

  1. Create a new feature module, eg. with the nest CLI:
$ nest generate module event
  1. Create a Data Transfer Object (DTO) inside a file named event.dto.ts:
export class EventDTO {
  id?: string;
  name: string;
  type: string;
  createdAt: Date;
}
  1. 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:

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:

{
  "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:
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

  1. Create a service that will abstract the CRUD operations:
$ 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:
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
async create(eventDto: EventDTO): Promise<Event> {
  const { resource } = await this.eventContainer.items.create<Event>(
    eventDto,
  );
  return resource;
}
READ

Fetches all the results of the query.

async getEvents(): Promise<Event[]> {
  const querySpec = {
    query: 'SELECT * FROM events',
  };

  const { resources } = await this.eventContainer.items
    .query<Event>(querySpec)
    .fetchAll();
  return resources;
}

Fetch a single resource.

async getEvent(id: string, partitionKey: string | string[]): Promise<Event> {
  const { resource } = await this.eventContainer
        .item(id, type)
        .read<Event>();
  return resource;
}
UPDATE

Replaces an item in the database.

async updateEvent(
  id: string,
  partitionKey: string | string[],
  eventData: EventDTO,
): Promise<Event> {
  let { resource: item } = await this.eventContainer
    .item(id, type)
    .read<Event>();

  item = {
    ...item,
    ...eventData,
  };

  const { resource: replaced } = await this.eventContainer
    .item(id, type)
    .replace(item);

  return replaced;
}
DELETE

Deletes an item from the database.

async deleteEvent(id: string, partitionKey: string | string[]): Promise<Event> {
  const { resource: deleted } = await this.eventContainer
    .item(id, type)
    .delete<Event>();

  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:

this.eventContainer
        .item("1234", ['foo', 'bar'])
        .read<Event>();

Read more about Hierarchical Partition Keys.

For Azure Table Storage support

  1. Create or update your existing .env file with the following content:
AZURE_STORAGE_CONNECTION_STRING=
  1. IMPORTANT: Make sure to add your .env file to your .gitignore! The .env file MUST NOT be versioned on Git.

  2. Make sure to include the following call to your main.ts file:

if (process.env.NODE_ENV !== 'production') require('dotenv').config();

This line must be added before any other imports!

  1. The AzureTableStorageModule will automatically read the AZURE_STORAGE_CONNECTION_STRING environment variable and use it to connect to your Azure Storage account.

Example

Check out the Table Storage example project included in the sample folder

Prepare your entity

  1. Create a new feature module, eg. with the nest CLI:
$ nest generate module event
  1. Create a Data Transfer Object (DTO) inside a file named event.dto.ts:
export class EventDTO {
  name: string;
  type: string;
}
  1. 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:
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:
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:

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 name
  • createTableIfNotExists: 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 yourself before querying it!

CRUD operations

  1. Create a service that will abstract the CRUD operations:
$ nest generate service event
  1. Use the @InjectRepository(Event) to get an instance of the Azure Repository for the entity definition created earlier:
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<Event>,
  ) {}
}

The AzureTableStorageRepository provides a list of public methods for managing various CRUD operations:

CREATE

create(entity: T): Promise<T | null>: creates a new entity.

  async create(event: Event): Promise<Event> {
    return await this.eventRepository.create(event);
  }
READ

find(partitionKey: string, rowKey: string): Promise<T>: finds one entity using its partitionKey and rowKey.

  async find(partitionKey: string, rowKey: string): Promise<Event> {
    return await this.eventRepository.find(partitionKey, rowKey);
  }

findAll(): Promise<T[]>: finds all entities (NOTE: odata filters are not supported yet).

  async findAll(): Promise<Event[]> {
    return await this.eventRepository.findAll();
  }
UPDATE

update(partitionKey: string, rowKey: string, entity: T): Promise<T>: Updates an entity using a "merge" strategy.

  async update(
    partitionKey: string,
    rowKey: string,
    event: Event,
  ): Promise<Event> {
    return await this.eventRepository.update(partitionKey, rowKey, event);
  }
DELETE

delete(partitionKey: string, rowKey: string): Promise<DeleteTableEntityResponse>: Removes an entity from the table.

  async delete(partitionKey: string, rowKey: string): Promise<void> {
    await this.eventRepository.delete(partitionKey, rowKey);
  }

Support

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.

Stay in touch

License

Nest is MIT licensed.

More Repositories

1

nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
TypeScript
67,297
star
2

awesome-nestjs

A curated list of awesome things related to NestJS 😎
10,616
star
3

nest-cli

CLI tool for Nest applications 🍹
TypeScript
1,939
star
4

typeorm

TypeORM module for Nest framework (node.js) 🍇
TypeScript
1,906
star
5

typescript-starter

Nest framework TypeScript starter ☕
TypeScript
1,854
star
6

swagger

OpenAPI (Swagger) module for Nest framework (node.js) 🌎
TypeScript
1,671
star
7

graphql

GraphQL (TypeScript) module for Nest framework (node.js) 🍷
TypeScript
1,453
star
8

docs.nestjs.com

The official documentation https://docs.nestjs.com 📕
TypeScript
1,190
star
9

cqrs

A lightweight CQRS module for Nest framework (node.js) 🎈
TypeScript
827
star
10

terminus

Terminus module for Nest framework (node.js) 🤖
TypeScript
668
star
11

throttler

A rate limiting module for NestJS to work with Fastify, Express, GQL, Websockets, and RPC 🧭
TypeScript
619
star
12

bull

Bull module for Nest framework (node.js) 🐮
TypeScript
602
star
13

jwt

JWT utilities module based on the jsonwebtoken package 🔓
TypeScript
599
star
14

mongoose

Mongoose module for Nest framework (node.js) 🍸
TypeScript
520
star
15

config

Configuration module for Nest framework (node.js) 🍓
TypeScript
513
star
16

passport

Passport module for Nest framework (node.js) 🔑
TypeScript
497
star
17

serve-static

Serve static websites (SPA's) using Nest framework (node.js) 🥦
TypeScript
454
star
18

ng-universal

Angular Universal module for Nest framework (node.js) 🌷
TypeScript
441
star
19

elasticsearch

Elasticsearch module based on the official elasticsearch package 🌿
TypeScript
382
star
20

schematics

Nest architecture element generation based on Angular schematics 🎬
TypeScript
382
star
21

mapped-types

Configuration module for Nest framework (node.js) 🐺
TypeScript
374
star
22

schedule

Schedule module for Nest framework (node.js) ⏰
TypeScript
350
star
23

sequelize

Sequelize module for Nest framework (node.js) 🍈
TypeScript
231
star
24

axios

Axios module for Nest framework (node.js) 🗂
TypeScript
219
star
25

event-emitter

Event Emitter module for Nest framework (node.js) 🦋
TypeScript
193
star
26

serverless-core-deprecated

[Deprecated] Serverless Core module for Nest framework (node.js) 🦊
TypeScript
171
star
27

azure-func-http

Azure Functions HTTP adapter for Nest framework (node.js) 🌥
TypeScript
151
star
28

nestjs.com

The official website https://nestjs.com 🏆
HTML
135
star
29

courses.nestjs.com

Official NestJS Courses website https://courses.nestjs.com 🏡
HTML
126
star
30

cache-manager

Cache manager module for Nest framework (node.js) 🗃
TypeScript
118
star
31

javascript-starter

Nest framework JavaScript (ES6, ES7, ES8) + Babel starter 🍰
JavaScript
117
star
32

azure-storage

Azure Storage module for Nest framework (node.js) ☁️
TypeScript
86
star
33

enterprise.nestjs.com

The official website https://enterprise.nestjs.com 🌁
HTML
18
star
34

newsletter.nestjs.com

Official NestJS Newsletter website https://newsletter.nestjs.com 📩
HTML
12
star