@showroomprive/azure-appconfig
Version:
A library to use Azure App Configuration in NestJS
231 lines (182 loc) • 7.69 kB
Markdown
# @showroomprive/azure-appconfig
A library to use Azure App Configuration in NestJS.
It will decompose Azure App Configuration Data into an interface.
# Table of Contents
- [@showroomprive/azure-appconfig](#showroompriveazure-appconfig)
- [Table of Contents](#table-of-contents)
- [Requirements](#requirements)
- [Dependencies](#dependencies)
- [Dev Dependencies](#dev-dependencies)
- [Peer Dependencies](#peer-dependencies)
- [Data Description](#data-description)
- [Installation](#installation)
- [Configuration](#configuration)
- [**app.module.ts**](#appmodulets)
- [Usage](#usage)
## Requirements
To use this library, the following requirements need to be met :
| Library Name | Version | Description |
|--------------------|---------|-----------------------------------------------------------------------------|
| @nestjs/common | ^10.4.8 | Common utilities used by NestJS applications. |
| @nestjs/core | ^10.0.0 | The core package of the NestJS framework. |
| rxjs | ^7.8.1 | A library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code. |
| @nestjs/config | ^3.3.0 | A module for managing application configuration in NestJS. |
## Dependencies
| Dependency | Version |
|-----------------------------|----------|
| @nestjs/common | ^11.0.11 |
| @azure/app-configuration | ^1.8.0 |
| @azure/identity | ^4.7.0 |
| @azure/keyvault-secrets | ^4.9.0 |
| @nestjs/config | ^4.0.1 |
| @nestjs/core | ^11.0.11 |
| rxjs | ^7.8.2 |
### Dev Dependencies
| Dependency | Version |
|-----------------------------|----------|
| @types/node | ^22.13.9 |
| typescript | ^5.8.2 |
### Peer Dependencies
| Dependency | Version |
|-----------------------------|----------|
| @nestjs/common | ^11.0.11 |
| @nestjs/core | ^11.0.11 |
| rxjs | ^7.8.2 |
| @nestjs/config | ^4.0.1 |
## Data Description
The data is described like this :
```typescript
export interface ApplicationSettings<T> {
[key: string]: T | GeneralSettings;
General: GeneralSettings;
Application: T;
}
```
`General` property will have all data that can be used by any application, his prefix in Azure App Configuration is : **SRP**.
`Application` property is a configuration that will be unique for each application, his prefix in Azure App Configuration is equals to the value of `APP_CONFIG_NAME` environnement variable.
## Installation
To install the package, run:
```sh
npm install @showroomprive/azure-appconfig
```
## Configuration
To use the library, several environment variables need to be provided in a `.env` file at the root:
| Variable Name | Description |
|-------------------|--------------------------------------------------|
| APP_CONFIG_URL | The URL of the Azure App Configuration instance. |
| ENVIRONMENT | The current environment (e.g., dev, prod, test, local). |
| APP_CONFIG_NAME | The name of the Azure App Configuration prefix. |
For local developpement, the variable `ENVIRONMENT` is mandatory, we won't reach the Azure App Configuration, we use a json file that is parsed instead.
The configuration is splitted in 2 parts :
- General part (prefix in Azure App Configuration : **SRP**)
- Application part (prefix in Azure App Configuration: value of `APP_CONFIG_NAME` environnement variable)
The local configuration should be at the root of the project (near `package.json` and `.env` files):
The file should be named : **local.config.json** :
```json
{
"SampleSettings": {
"SampleSetting1": "Value1",
"SampleSetting2": "Value2"
},
"SRP": {
"InternalBasePaths": {
"BetaWebApp": "/beta/webapp"
}
}
}
```
> **Warning:** This file may contain sensitive information. Ensure it is not committed to version control and is kept local to your development environment.
### **app.module.ts**
We need imports 2 modules:
- ConfigModule (global way to share configuration through the whole application)
- AzureAppconfigModule
We need to add one provider to access the data :
- ApplicationSettingsService
So the changes will be like that :
```typescript
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { ConfigModule } from '@nestjs/config';
import { ApplicationSettingsService, AzureAppconfigModule } from '@showroomprive/azure-appconfig';
import { azureAppconfigLoader } from "@showroomprive/azure-appconfig/dist/azure-appconfig-loader";
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true,
load: [
azureAppconfigLoader
],
}),
AzureAppconfigModule],
controllers: [AppController],
providers: [ ApplicationSettingsService],
})
export class AppModule {}
```
## Usage
To access the data we need to use Dependency injection for the ApplicationSettingsService and then we will be able to access the General and Application properties.
For example :
```typescript
import { Controller, Get } from '@nestjs/common';
import { ApplicationSettingsService } from '@showroomprive/azure-appconfig';
import { SampleSettings } from './models/sample-settings';
import { GeneralSettings } from '@showroomprive/azure-appconfig/dist/models/general-settings';
@Controller()
export class AppController {
constructor(private readonly azureAppConfiguration: ApplicationSettingsService<SampleSettings>) {
}
@Get("general")
getGeneralSettings(): GeneralSettings | undefined {
return this.azureAppConfiguration.General;
}
@Get("application")
getApplicationSettings(): SampleSettings | undefined {
return this.azureAppConfiguration.Application;
}
}
```
Where SampleSettings is an interface :
```typescript
export interface SampleSettings {
SampleSetting1: string;
SampleSetting2: string;
}
```
The `ApplicationSettingsService<SampleSettings>` use `ConfigService` to get the configurations and configure 2 properties, General and Application :
these 2 get the values like this :
- General : `configService.get<SampleSettings>('General')`
- Application : `configService.get<SampleSettings>('Application')`
For factory, we can access the configuration on `ConfigService` from `@nestjs/config`
There is a sample of how to do it with knex :
```typescript
import { Global, Module } from '@nestjs/common';
import Knex from 'knex';
import { Model } from 'objection';
import { ConfigService } from '@nestjs/config';
import { SampleSettings } from 'src/models/sample-settings';
@Global()
@Module({
providers: [
{
provide: 'KnexConnection',
useFactory: async (configService : ConfigService) => {
const config = configService.get<SampleSettings>('Application');
const knex = Knex({
client: 'mssql',
connection: {
host: config.DatabaseSettings.Host,
user: config.DatabaseSettings.User,
password: config.DatabaseSettings.Password,
database: config.DatabaseSettings.Name,
port: Number(config.DatabaseSettings.Port),
}
});
Model.knex(knex);
return knex;
},
inject: [ConfigService],
},
],
exports: ['KnexConnection'],
})
export class DatabaseModule {}
```