résumer
Dans la première partie, créer une application mutualisée Dans Nest.js – Partie 1, nous avons configuré le framework Nest.js et configuré et testé l’application d’architecture de microservices à l’aide de Nest.js. Dans sa deuxième partie, nous avons utilisé Sequelize et Mongoose pour accéder à la base de données et testé à la fois la base de données MySQL et MongoDB.
Connexion asynchrone
Dans cette partie; nous verrons comment laisser l’application se connecter à plusieurs bases de données en fonction de la requête. Puisqu’il s’agit d’une application multi-tenant, chaque locataire a sa propre base de données contenant ses données accédant à la même application, donc l’application doit se connecter à différentes bases de données. Nous allons changer la méthode d’option de dépôt de passe et utiliser forRootAsync()
à la place de forRoot()
, nous devons utiliser une classe personnalisée pour la configuration.
Pour Sequelize et Mongoose, ajoutez les éléments suivants :
MongooseModule.forRootAsync({
useClass:MongooseConfigService
}),
SequelizeModule.forRootAsync({
useClass:SequelizeConfigService
})
Nous allons créer un fichier de configuration et deux classes : MongooseConfigService
et SequelizeConfigService
Le plan ici est d’ajouter une injection pour chaque demande entrante et d’utiliser un domaine pour basculer entre les connexions.
Nous devons donc utiliser @Injectable({scope:Scope.REQUEST})
, et sur le constructeur de classe, on utilise @Inject(REQUEST) private read-only request
afin que nous puissions obtenir des informations sur l’hôte à partir des données de demande.
Par exemple, disons que le domaine est example.com, et nous avons un locataire appelé company1
, le domaine sera company1.example.com. Même chose pour company2
locataire, le domaine sera company2.example.com et ainsi de suite.
config/MongooseConfigService.ts
import { Inject, Injectable, Scope } from "@nestjs/common";
import { REQUEST } from "@nestjs/core";
import { MongooseModuleOptions, MongooseOptionsFactory } from "@nestjs/mongoose";
@Injectable({scope:Scope.REQUEST})
export class MongooseConfigService implements MongooseOptionsFactory {
constructor(@Inject(REQUEST) private readonly request,){}
createMongooseOptions(): MongooseModuleOptions {
let domain:string[]
let database="database_development"
if(this.request.data ){
domain=this.request.data['host'].split('.')
console.log(this.request)
}
else{
domain=this.request['headers']['host'].split('.')
}
console.log(domain)
if(domain[0]!='127' && domain[0]!='www' && domain.length >2){
database="tenant_"+domain[0]
console.log('current DB',database)
}
return {
uri: 'mongodb://localhost:27017/'+database,
};
}
}
config/SequelizeConfigService.ts
import { Inject, Injectable, Scope } from "@nestjs/common";
import { REQUEST } from "@nestjs/core";
import { CONTEXT, RedisContext, RequestContext } from "@nestjs/microservices";
import { SequelizeModuleOptions, SequelizeOptionsFactory} from "@nestjs/sequelize";
@Injectable({scope:Scope.REQUEST})
export class SequelizeConfigService implements SequelizeOptionsFactory {
constructor(@Inject(REQUEST) private readonly request:RequestContext){}
createSequelizeOptions(): SequelizeModuleOptions {
let domain:string[]
let database="database_development"
if(this.request.data ){
domain=this.request.data['host'].split('.')
console.log(this.request)
}
else{
domain=this.request['headers']['host'].split('.')
}
console.log(domain)
if(domain[0]!='127' && domain[0]!='www' && domain.length >2){
database="tenant_"+domain[0]
console.log('current DB',database)
}
return {
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'ismaeil',
password: 'root',
database: database,
autoLoadModels: true,
synchronize: true,
};
}
}
Essai
Après avoir terminé la configuration, nous devons travailler pour le tester car nous devons mapper notre hôte local et notre IP à un domaine. Je vais essayer d’utiliser deux façons de tester l’application en local mais pour la production, ce sera une configuration chez votre fournisseur de domaine.
1- Modifiez le fichier hosts sur votre machine locale et modifiez ce fichier à chaque fois que vous ajoutez un locataire
Accédez au fichier suivant sous Linux : /etc/hosts
et sous windows : c:windowssystem32driversetchosts
et ajouter
## lines
127.0.0.1 example.com
127.0.0.1 company1.example.com
127.0.0.1 company2.example.com
2- Utiliser le DNS local
Sous Linux, vous pouvez installer Dnsmasq et suivre ces étapes :
1- Installez dnsmasq dans NetworkManager.
2- Ajouter le fichier de configuration
sudo nano /etc/NetworkManager/dnsmasq.d/dnsmasq-localhost.conf
.ajoutez cette ligne dans le fichier :
address=/.example.com/127.0.0.1
3- Redémarrez le service
sudo systemctl reload NetworkManager
.
Le code source est disponible dans la multi-base de données de la branche Git.
C’est tout! Dans la partie 4, nous allons ajouter un niveau de sécurité et des rôles d’utilisateurs.