{"id":14978599,"url":"https://github.com/nestjs/azure-database","last_synced_at":"2025-04-08T10:33:52.947Z","repository":{"id":35111100,"uuid":"205937577","full_name":"nestjs/azure-database","owner":"nestjs","description":"Azure CosmosDB Database module for Nest framework (node.js) ☁️","archived":false,"fork":false,"pushed_at":"2024-10-29T08:33:40.000Z","size":5955,"stargazers_count":106,"open_issues_count":21,"forks_count":52,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-29T09:51:59.843Z","etag":null,"topics":["azure","cloud","cosmosdb","database","javascript","nest","nestjs","nodejs","typescript"],"latest_commit_sha":null,"homepage":"https://nestjs.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nestjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-02T21:14:18.000Z","updated_at":"2024-10-29T08:32:35.000Z","dependencies_parsed_at":"2023-09-22T22:51:03.434Z","dependency_job_id":"7d04c2c6-b2db-4183-b53d-7d37cbbe0ff3","html_url":"https://github.com/nestjs/azure-database","commit_stats":{"total_commits":1035,"total_committers":24,"mean_commits":43.125,"dds":"0.41932367149758454","last_synced_commit":"b3cf4ff31a45bd443c76df63e4675731a44d04b9"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjs%2Fazure-database","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjs%2Fazure-database/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjs%2Fazure-database/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjs%2Fazure-database/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nestjs","download_url":"https://codeload.github.com/nestjs/azure-database/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246403911,"owners_count":20771530,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","cloud","cosmosdb","database","javascript","nest","nestjs","nodejs","typescript"],"created_at":"2024-09-24T13:58:00.058Z","updated_at":"2025-04-01T09:25:45.587Z","avatar_url":"https://github.com/nestjs.png","language":"TypeScript","funding_links":["https://opencollective.com/nest","https://paypal.me/kamilmysliwiec"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://nestjs.com/\" target=\"blank\"\u003e\u003cimg src=\"https://nestjs.com/img/logo_text.svg\" width=\"320\" alt=\"Nest Logo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master\n[travis-url]: https://travis-ci.org/nestjs/nest\n[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux\n[linux-url]: https://travis-ci.org/nestjs/nest\n\n  \u003cp align=\"center\"\u003eA progressive \u003ca href=\"http://nodejs.org\" target=\"blank\"\u003eNode.js\u003c/a\u003e framework for building efficient and scalable server-side applications.\u003c/p\u003e\n    \u003cp align=\"center\"\u003e\n\u003ca href=\"https://www.npmjs.com/~nestjscore\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@nestjs/core.svg\" alt=\"NPM Version\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/~nestjscore\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/@nestjs/core.svg\" alt=\"Package License\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/~nestjscore\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/@nestjs/core.svg\" alt=\"NPM Downloads\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://coveralls.io/github/nestjs/nest?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#5\" alt=\"Coverage\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://discord.gg/G7Qnnhy\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/discord-online-brightgreen.svg\" alt=\"Discord\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/nest#backer\"\u003e\u003cimg src=\"https://opencollective.com/nest/backers/badge.svg\" alt=\"Backers on Open Collective\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/nest#sponsor\"\u003e\u003cimg src=\"https://opencollective.com/nest/sponsors/badge.svg\" alt=\"Sponsors on Open Collective\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://paypal.me/kamilmysliwiec\"\u003e\u003cimg src=\"https://img.shields.io/badge/Donate-PayPal-dc3d53.svg\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://twitter.com/nestframework\"\u003e\u003cimg src=\"https://img.shields.io/twitter/follow/nestframework.svg?style=social\u0026label=Follow\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n  \u003c!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)\n  [![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)--\u003e\n\n## Description\n\nAzure Database ([Table Storage](http://bit.ly/nest_azure-storage-table), [Cosmos DB - NoSQL](https://azure.microsoft.com/en-us/services/cosmos-db/)) module for [Nest](https://github.com/nestjs/nest) framework (node.js)\n\n## Disclaimer\n\nYou are reading the documentation for version 3. If you are looking for version 2 documentation, [click here](https://github.com/nestjs/azure-database/tree/legacy-v2). Please also note that version 2 is no longer maintained and will not receive any updates!\n\n## Before Installation\n\nFor Cosmos DB (NoSQL ONLY)\n\n1. Create a Cosmos DB account and resource ([read more](https://learn.microsoft.com/azure/cosmos-db/nosql/quickstart-portal))\n2. Note down the \"URI\", Database name and the \"Primary Key\" (or \"Secondary Key\") - You will need them later\n\nFor Table Storage\n\n1. Create a Storage account and resource ([read more](https://learn.microsoft.com/azure/storage/tables/table-storage-quickstart-portal))\n2. Note down the \"Connection string\" - You will need it later\n\n## Installation\n\n```bash\n$ npm i --save @nestjs/azure-database\n```\n\n## Usage\n\n### For Azure Cosmos DB support\n\n1. Create or update your existing `.env` file with the following content:\n\n```\nAZURE_COSMOS_DB_NAME=\nAZURE_COSMOS_DB_ENDPOINT=\nAZURE_COSMOS_DB_KEY=\n```\n\n2. **IMPORTANT: Make sure to add your `.env` file to your .gitignore! The `.env` file MUST NOT be versioned on Git.**\n\n3. Make sure to include the following call to your `main.ts` file:\n\n```typescript\nif (process.env.NODE_ENV !== 'production') require('dotenv').config();\n```\n\n\u003e This line must be added before any other imports!\n\n### Example\n\n\u003e Note: Check out the CosmosDB example project included in the [sample folder](https://github.com/nestjs/azure-database/tree/master/sample/cosmos-db)\n\n#### Prepare your entity\n\n0. Create a new feature module, eg. with the nest CLI:\n\n```shell\n$ nest generate module event\n```\n\n1. Create a Data Transfer Object (DTO) inside a file named `event.dto.ts`:\n\n```typescript\nexport class EventDTO {\n  id?: string;\n  name: string;\n  type: string;\n  createdAt: Date;\n}\n```\n\n2. Create a file called `event.entity.ts` and describe the entity model using the provided decorators:\n\n- `@CosmosPartitionKey(value: string | HierarchicalPartitionKey)`: Represents the `PartitionKey` or [`HierarchicalPartitionKey`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/cosmosdb/cosmos#crud-on-container-with-hierarchical-partition-key) of the entity (**required**).\n\n- `@CosmosDateTime(value?: string)`: For DateTime values.\n\n**Important:** Using a Hierarchical Partition Key requires a container that uses hierarchical partition keys, [read more](https://learn.microsoft.com/azure/cosmos-db/hierarchical-partition-keys).\n\nFor instance, the shape of the following entity:\n\n```typescript\nimport { CosmosDateTime, CosmosPartitionKey } from '@nestjs/azure-database';\nimport { PartitionKeyDefinitionVersion, PartitionKeyKind } from '@azure/cosmos';\n\n@CosmosPartitionKey({\n  paths: ['/name', '/type/label'],\n  version: PartitionKeyDefinitionVersion.V2,\n  kind: PartitionKeyKind.MultiHash,\n})\nexport class Event {\n  id?: string;\n  name: string;\n  type: {\n    label: string;\n  };\n  @CosmosDateTime() createdAt: Date;\n}\n```\n\nWill be automatically converted to:\n\n```json\n{\n  \"name\": \"NestJS Meetup\",\n  \"type\": {\n    \"label\": \"Meetup\"\n  },\n  \"createdAt\": \"2019-11-15T17:05:25.427Z\"\n}\n```\n\n1. Import the `AzureCosmosDbModule` inside your Nest feature module `event.module.ts`:\n\n```typescript\nimport { AzureCosmosDbModule } from '@nestjs/azure-database';\nimport { Module } from '@nestjs/common';\nimport { Event } from './event.entity';\n\n@Module({\n  imports: [\n    AzureCosmosDbModule.forRoot({\n      dbName: process.env.AZURE_COSMOS_DB_NAME,\n      endpoint: process.env.AZURE_COSMOS_DB_ENDPOINT,\n      key: process.env.AZURE_COSMOS_DB_KEY,\n      retryAttempts: 1,\n    }),\n    AzureCosmosDbModule.forFeature([{ dto: Event }]),\n  ],\n})\nexport class EventModule {}\n```\n\n#### CRUD operations\n\n0. Create a service that will abstract the CRUD operations:\n\n```shell\n$ nest generate service event\n```\n\n1. Use the `@InjectModel(Event)` to get an instance of the Azure Cosmos DB [Container](https://docs.microsoft.com/en-us/javascript/api/@azure/cosmos/container) for the entity definition created earlier:\n\n```typescript\nimport { InjectModel } from '@nestjs/azure-database';\nimport type { Container } from '@azure/cosmos';\nimport { Injectable } from '@nestjs/common';\nimport { Event } from './event.entity';\n\n@Injectable()\nexport class EventService {\n  constructor(\n    @InjectModel(Event)\n    private readonly eventContainer: Container,\n  ) {}\n}\n```\n\n`@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.\n\n**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](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/cosmosdb/cosmos/README.md).**\n\n##### CREATE\n\n```typescript\nasync create(eventDto: EventDTO): Promise\u003cEvent\u003e {\n  const { resource } = await this.eventContainer.items.create\u003cEvent\u003e(\n    eventDto,\n  );\n  return resource;\n}\n```\n\n##### READ\n\nFetches all the results of the query.\n\n```typescript\nasync getEvents(): Promise\u003cEvent[]\u003e {\n  const querySpec = {\n    query: 'SELECT * FROM events',\n  };\n\n  const { resources } = await this.eventContainer.items\n    .query\u003cEvent\u003e(querySpec)\n    .fetchAll();\n  return resources;\n}\n```\n\nFetch a single resource.\n\n```typescript\nasync getEvent(id: string, partitionKey: string | string[]): Promise\u003cEvent\u003e {\n  const { resource } = await this.eventContainer\n        .item(id, type)\n        .read\u003cEvent\u003e();\n  return resource;\n}\n```\n\n##### UPDATE\n\nReplaces an item in the database.\n\n```typescript\nasync updateEvent(\n  id: string,\n  partitionKey: string | string[],\n  eventData: EventDTO,\n): Promise\u003cEvent\u003e {\n  let { resource: item } = await this.eventContainer\n    .item(id, type)\n    .read\u003cEvent\u003e();\n\n  item = {\n    ...item,\n    ...eventData,\n  };\n\n  const { resource: replaced } = await this.eventContainer\n    .item(id, type)\n    .replace(item);\n\n  return replaced;\n}\n```\n\n##### DELETE\n\nDeletes an item from the database.\n\n```typescript\nasync deleteEvent(id: string, partitionKey: string | string[]): Promise\u003cEvent\u003e {\n  const { resource: deleted } = await this.eventContainer\n    .item(id, type)\n    .delete\u003cEvent\u003e();\n\n  return deleted;\n}\n```\n\n#### Hierarchical Partition Keys\n\nIf 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:\n\n```javascript\nthis.eventContainer\n        .item(\"1234\", ['foo', 'bar'])\n        .read\u003cEvent\u003e();\n```\n\nRead more about [Hierarchical Partition Keys](https://learn.microsoft.com/en-us/azure/cosmos-db/hierarchical-partition-keys?tabs=javascript-v4%2Carm-json).\n\n### For Azure Table Storage support\n\n1. Create or update your existing `.env` file with the following content:\n\n```\nAZURE_STORAGE_CONNECTION_STRING=\n```\n\n2. **IMPORTANT: Make sure to add your `.env` file to your .gitignore! The `.env` file MUST NOT be versioned on Git.**\n\n3. Make sure to include the following call to your `main.ts` file:\n\n```typescript\nif (process.env.NODE_ENV !== 'production') require('dotenv').config();\n```\n\n\u003e This line must be added before any other imports!\n\n4. The `AzureTableStorageModule` will automatically read the `AZURE_STORAGE_CONNECTION_STRING` environment variable and use it to connect to your Azure Storage account.\n\n### Example\n\nCheck out the Table Storage example project included in the [sample folder](https://github.com/nestjs/azure-database/tree/master/sample/table-storage)\n\n#### Prepare your entity\n\n0. Create a new feature module, eg. with the nest CLI:\n\n```shell\n$ nest generate module event\n```\n\n1. Create a Data Transfer Object (DTO) inside a file named `event.dto.ts`:\n\n```typescript\nexport class EventDTO {\n  name: string;\n  type: string;\n}\n```\n\n2. 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:\n\n```typescript\nexport class Event {\n  partitionKey: string; // required\n  rowKey: string; // required\n  name: string;\n  type: string;\n}\n```\n\n1. Import the `AzureTableStorageModule` inside your Nest feature module `event.module.ts`:\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { AzureTableStorageModule } from '@nestjs/azure-database';\n\n@Module({\n  imports: [AzureTableStorageModule.forFeature(Event)],\n})\nexport class EventModule {}\n```\n\nYou can optionally pass in the following arguments:\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { AzureTableStorageModule } from '@nestjs/azure-database';\n\n@Module({\n  imports: [\n    AzureTableStorageModule.forFeature(Event, {\n      table: 'foobar',\n      createTableIfNotExists: true,\n    }),\n  ],\n})\nexport class EventModule {}\n```\n\n- `table: string`: The name of the table. If not provided, the name of the `Event` entity will be used as a table name\n- `createTableIfNotExists: boolean`: Whether to automatically create the table if it doesn't exists or not:\n  - If `true` the table will be created during the startup of the app.\n  - If `false` the table will not be created. **You will have to create the table by yourself before querying it!**\n\n#### CRUD operations\n\n0. Create a service that will abstract the CRUD operations:\n\n```shell\n$ nest generate service event\n```\n\n1. Use the `@InjectRepository(Event)` to get an instance of the Azure `Repository` for the entity definition created earlier:\n\n```typescript\nimport { InjectRepository, Repository } from '@nestjs/azure-database';\nimport { Injectable } from '@nestjs/common';\nimport { Event } from './event.entity';\n\n@Injectable()\nexport class EventService {\n  constructor(\n    @InjectRepository(Event)\n    private readonly eventRepository: Repository\u003cEvent\u003e,\n  ) {}\n}\n```\n\nThe `AzureTableStorageRepository` provides a list of public methods for managing various CRUD operations:\n\n##### CREATE\n\n`create(entity: T): Promise\u003cT | null\u003e`: creates a new entity.\n\n```typescript\n  async create(event: Event): Promise\u003cEvent\u003e {\n    return await this.eventRepository.create(event);\n  }\n```\n\n##### READ\n\n`find(partitionKey: string, rowKey: string): Promise\u003cT\u003e`: finds one entity using its `partitionKey` and `rowKey`.\n\n```typescript\n  async find(partitionKey: string, rowKey: string): Promise\u003cEvent\u003e {\n    return await this.eventRepository.find(partitionKey, rowKey);\n  }\n```\n\n`findAll(options: { queryOptions?: TableEntityQueryOptions }): Promise\u003cT[]\u003e`: finds all entities.\n\n```typescript\n  async findAll(options: { queryOptions?: TableEntityQueryOptions }): Promise\u003cEvent[]\u003e {\n    return await this.eventRepository.findAll();\n  }\n```\n\n##### UPDATE\n\n`update(partitionKey: string, rowKey: string, entity: T): Promise\u003cT\u003e`: Updates an entity using a \"merge\" strategy.\n\n```typescript\n  async update(\n    partitionKey: string,\n    rowKey: string,\n    event: Event,\n  ): Promise\u003cEvent\u003e {\n    return await this.eventRepository.update(partitionKey, rowKey, event);\n  }\n```\n\n##### DELETE\n\n`delete(partitionKey: string, rowKey: string): Promise\u003cDeleteTableEntityResponse\u003e`: Removes an entity from the table.\n\n```typescript\n  async delete(partitionKey: string, rowKey: string): Promise\u003cvoid\u003e {\n    await this.eventRepository.delete(partitionKey, rowKey);\n  }\n```\n\n## Support\n\nNest 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](https://docs.nestjs.com/support).\n\n## Stay in touch\n\n- Author - [Wassim Chegham](https://wassim.dev)\n- Website - [https://wassim.dev](https://wassim.dev/)\n- Twitter - [@manekinekko](https://twitter.com/manekinekko)\n\n## License\n\nNest is [MIT licensed](LICENSE).\n\n[edm-types]: http://bit.ly/nest-edm\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjs%2Fazure-database","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnestjs%2Fazure-database","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjs%2Fazure-database/lists"}