Dans Créer une application mutualisée dans Nest.js – Partie 1, nous avons configuré le framework Nest.js, configuré et testé l’application de microservice à l’aide de Nest.js.
Base de données
Nest nous donne tous les outils pour travailler avec n’importe quelle base de données SQL et NoSQL. Vous avez beaucoup d’options, vous pouvez également utiliser presque tous les ORM et bibliothèques dans Nest.js et dactylographié, comme Sequelize, TypeORM, Prisma et bien sûr la mangouste.
Dans cette application, nous allons travailler avec MySQL et MongoDB. Nous utiliserons également les bibliothèques Js populaires, notamment Sequelize en tant qu’ORM pour MySQL et mongoose pour MongoDB.
Intégration de base de données
Pour commencer à utiliser Sequelize, nous devons d’abord installer les dépendances requises, notamment @nestjs/Sequelize, MySQL2, car nous nous connecterons à la base de données MySQL et aux autres dépendances nécessaires.
$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
Dans les services, nous importerons SequelizeModule dans les modules principaux pour définir la configuration de la connexion :
ex : app.module.ts
@Module({
imports: [
SequelizeModule.forRoot({
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
models: [],
}),
],
})
Les forRoot()
La méthode inclura toutes les propriétés de configuration. Vous pouvez lire plus de détails ici.
Après avoir configuré la connexion, nous devons créer une entité de table. Par exemple, nous pouvons définir un modèle d’utilisateur dans le service utilisateur (ajoutera également la connexion dans le service) en créant user.model.ts qui ressemblera à ceci :
user.model.ts
/// imports
@Table({tableName:'Users'})
export class Users extends Model<Users> {
@Column( {allowNull: false })
firstName: string;
@Column( {allowNull: false })
lastName: string;
@Column( { allowNull: false,unique: true })
email: string;
@Column( {allowNull: false})
password: string;
@Column( { allowNull: false})
type: string;
}
Nous devrions également ajouter le dto :
créer-utilisateur-dto.ts
export class CreateUserDto{
readonly firstName:string
readonly lastName:string
readonly email:string
readonly password:string
readonly type:string
}
Et n’oubliez pas d’ajouter les utilisateurs dans le tableau des modèles dans forRoot()
Terminons maintenant l’installation et la configuration. Si vous n’avez pas de base de données, vous devez créer une table vide et modifier la configuration de Sequelize en ajoutant : autoLoadModels: true, synchronize: true
. Ensuite dans le module, vous ajouterez le référentiel en ajoutant SequelizeModule.forFeature([Users])
dans le tableau des importations. Dans notre cas, nous utilisons le module principal donc ce sera :
user-service.module.ts
@Module({
imports: [SequelizeModule.forRoot({
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'ismaeil',
password: 'root',
database: 'test',
autoLoadModels: true,
synchronize: true,
models: [Users],
}),SequelizeModule.forFeature([Users])],
controllers: [UserServiceController],
providers: [UserServiceService],
})
Et nous allons éditer le service principal pour ajouter findAll
et create
méthode:
service-utilisateur.service.ts
@Injectable()
export class UserServiceService {
constructor(
@InjectModel(Users)
private readonly userModel: typeof Users){}
async findAll(): Promise<Users[]> {
return this.userModel.findAll() ;
}
async create( createUserDto:CreateUserDto):Promise<Users> {
return this.userModel.create(<Users>createUserDto)
}
}
Enfin, éditez le contrôleur pour permettre l’utilisation des requêtes REST pour accéder et éditer la base de données :
user-service.controller.ts
@Controller('users')
export class UserServiceController {
constructor(private readonly userServiceService: UserServiceService) {}
@Get()
async findAll(){
return this.userServiceService.findAll();
}
@Post()
async createUser(@Body() createUserDto:CreateUserDto){
return this.userServiceService.create(createUserDto)
}
}
Lancez maintenant le navigateur et testez http://127.0.0.1:3003/users. Cela devrait accéder à la base de données et créer une table pour la première fois et retourner un tableau vide. Nous pouvons ajouter des données à l’aide d’une requête POST :
Conseils supplémentaires
Si nous avons une base de données existante et que nous devons importer des tables avec des types sans trop de travail, nous pouvons utiliser sequelize-typescript-generator.
Vous pouvez effectuer une recherche à ce sujet pour voir comment cela fonctionne, mais voici quelques étapes simples :
- Téléchargez et installez npx
- Créer un dossier pour enregistrer les modèles dactylographiés de sortie
mkdir models
- Installez sequelize-typescript-generator sur votre machine :
npm install -g sequelize-typescript-generator
- Installez le pilote mysql :
npm install -g mysql2
- Exécutez la commande :
npx stg -D mysql -h localhost -p 3306 -d <databaseName> -u <username> -x <password> --indices --case camel --out-dir models --clean
Code source disponible dans la connexion à la base de données de la branche Git.
Tout comme le précédent, nous devons installer des dépendances pour utiliser MongoDB dans Nest :
$ npm install --save @nestjs/mongoose mongoose
Importez MongooseModule dans le module racine
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost:27017/test')],
})
forRoot()
accepte la même configuration que mongoose.connect() du package Mongoose.
Nous utiliserons la base de données MongoDB dans le service de notification. Tout d’abord, nous ajouterons forRoot()
dans le module racine et créera un module enfant appelé message pour servir les messages de notification.
Le module racine ressemblera à ceci :
notification.module.ts
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost:27017/test'),
MessageModule],
controllers: [NotificationController],
providers: [NotificationService],
})
Parce que nous utilisons mongoose, nous devons créer un schéma et ensuite importer le référentiel dans un module.
Dans src/message/schemes, nous allons créer un fichier message.schema.ts qui ressemblera à ceci :
export type MessageSchemaDocument = MessageSchema & Document;
@Schema()
export class MessageSchema{
@Prop()
name: string
@Prop()
createdAt: Date
@Prop({type:mongoose.Schema.Types.Mixed})
data: Record<string, any>
}
export const MessageSchemaSchema = SchemaFactory.createForClass(MessageSchema);
Ajoutez le code suivant dans message.module :
message.module.ts
@Module({
imports: [MongooseModule.forFeature([{name:MessageSchema.name,schema:MessageSchemaSchema}])],
controllers: [MessageController],
providers: [MessageService],
})
Et ajoutez les méthodes suivantes dans le service de messagerie :
message.service.ts
@Injectable()
export class MessageService {
constructor(@InjectModel(MessageSchema.name) private readonly messageModel: Model<MessageSchemaDocument>) {}
async findAll () {
return await this.messageModel.find().exec()
}
async create (messageDto:MessageDto) {
return await this.messageModel.create(messageDto)
}
}
Pour l’utiliser dans le type de corps de réponse, nous pouvons créer MessageDto :
export class MessageDto {
readonly name: string
readonly createdAt:Date = new Date();
readonly data?: any
}
Pour le mappage de la demande :
message.controller.ts
@Controller('message')
export class MessageController {
constructor(private readonly messagenService: MessageService) {}
@Get()
async findAll(){
return this.messagenService.findAll();
}
@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() messageDto:MessageDto){
return this.messagenService.create(messageDto);
}
}
Noter: Les tuyaux sont utilisés pour transformer et valider les données d’entrée, dans notre cas, nous pouvons utiliser @UsePipes(new ValidationPipe({ transform: true }))
pour définir les propriétés vides dans le Dto avec les valeurs par défaut. Pour plus de détails, reportez-vous à Pipes et validation.
Vous pouvez maintenant tester à l’aide d’une requête Post à l’URL http://127.0.0.1:3002/message with body :
{
"name":"validation",
"data":{"message":"testing validation message if it success","status":"valid"}
}
Pour récupérer tous les enregistrements, utilisez la requête Get http://127.0.0.1:3002/message et le code source disponible dans la branche Git mongodb-connection.
Alors, c’était tout pour le moment ! Dans la partie 3, nous terminerons la configuration de la base de données pour utiliser plusieurs bases de données en fonction de l’en-tête de la requête.