Dans cet article, nous allons découvrir la configuration de base de NestJS Swagger. La documentation est un aspect clé du développement d’applications. Fondamentalement, une bonne documentation API est importée pour que les clients utilisent efficacement nos API.
La spécification OpenAPI fournit un cadre pour la même chose. Fondamentalement, le framework est indépendant du langage. Cela le rend largement acceptable dans la communauté du développement. NestJS fournit également un module dédié pour activer Swagger et prend ainsi en charge la spécification OpenAPI. Fondamentalement, ce module permet de générer une documentation compatible OpenAPI à l’aide de décorateurs.
1 – Pose
La première étape consiste à installer les dépendances. Pour ce faire, exécutez la commande ci-dessous :
$ npm install --save @nestjs/swagger swagger-ui-express
Puisque nous utilisons express, nous installons le package swagger-ui-express. Cependant, pour Fastify, nous utilisons le package fastify-swagger.
2 – Amorçage de NestJS Swagger
L’étape suivante consiste à amorcer le module NestJS Swagger dans notre application. Pour ce faire, nous initialisons Swagger à l’aide de SwaggerModule dans le fichier main.ts.
Voir le code ci-dessous :
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder().setTitle('Demo Application')
.setDescription("Demo API Application")
.setVersion('v1')
.addTag('books')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
La première chose à remarquer ci-dessus est la classe DocumentBuilder. Fondamentalement, DocumentBuilder aide à structurer un document de base. Ce document confirme la spécification OpenAPI. Il nous permet de définir plusieurs propriétés telles que le titre, la description, etc. Dans l’exemple ci-dessus, nous définissons les propriétés du titre, de la description, de la version et de la balise. Enfin, nous appelons la méthode build() pour renvoyer une instance du document.
Ensuite, nous appelons la méthode createDocument() de la classe SwaggerModule. Cette méthode prend essentiellement deux arguments en entrée. Le premier est l’instance d’application. Le second est le document de configuration lui-même de l’étape précédente. Nous pouvons également fournir un troisième argument pour spécifier les options du document. Nous les vérifierons dans la section suivante.
Enfin, nous appelons le setup() méthode de la classe SwaggerModule. Cette méthode accepte plusieurs entrées comme ci-dessous :
- Le chemin pour monter l’interface utilisateur Swagger. Dans ce cas, nous spécifions le chemin comme API. Fondamentalement, cela signifie que l’interface utilisateur Swagger sera disponible sur http://localhost:3000/api.
- Une instance d’application.
- L’objet document est instancié à l’étape précédente.
- Options de configuration facultatives. Dans le code ci-dessus, nous ne les avons pas.
3 – Interface utilisateur de NestJS Swagger
Pour afficher quelque chose de significatif, nous allons rapidement rassembler quelques points de terminaison à des fins de démonstration.
Voir ci-dessous:
import { Body, Controller, Get, Param, Post, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { Book } from './book.model';
@Controller('books')
export class AppController {
constructor(private readonly appService: AppService) { }
@Post()
async createBook(@Res() response, @Body() book: Book) {
console.log("Book: ", book);
}
@Get()
async fetchAll(@Res() response) {
}
@Get('/:id')
async findById(@Res() response, @Param('id') id) {
console.log("Fetch Book for Id: ", id)
}
}
Vous pouvez en savoir plus sur les contrôleurs et les points de terminaison dans notre article détaillé sur les contrôleurs NestJS. Une fois la configuration de base en place, nous pouvons démarrer notre application à l’aide de la commande ci-dessous :
$ npm run start
L’interface utilisateur Swagger sera disponible sur http://localhost:3000/api. Voir la capture d’écran ci-dessous :
Comme vous pouvez le remarquer, le SwaggerModule reflète automatiquement tous nos points de terminaison. De plus, le reste des paramètres tels que le titre, la description, la version, etc., sont également présents.
Nous pouvons également télécharger le fichier Swagger JSON à partir de http://localhost:3000/api-json. Il ressemblera à ci-dessous :
{
"openapi": "3.0.0",
"paths": {
"/books": {
"post": {
"operationId": "AppController_createBook",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Book"
}
}
}
},
"responses": {
"201": {
"description": ""
}
}
},
"get": {
"operationId": "AppController_fetchAll",
"parameters": [],
"responses": {
"200": {
"description": ""
}
}
}
},
"/books/{id}": {
"get": {
"operationId": "AppController_findById",
"parameters": [],
"responses": {
"200": {
"description": ""
}
}
}
}
},
"info": {
"title": "Demo Application",
"description": "Demo API Application",
"version": "v1",
"contact": {}
},
"tags": [{
"name": "books",
"description": ""
}],
"servers": [],
"components": {
"schemas": {
"Book": {
"type": "object",
"properties": {}
}
}
}
}
4 – Options de configuration de NestJS Swagger
Comme indiqué précédemment, il est également possible de fournir des options de configuration NestJS Swagger supplémentaires. Ces options font partie de la classe SwaggerDocumentOptions.
Voir ci-dessous:
export interface SwaggerDocumentOptions {
/**
* List of modules to include in the specification
*/
include?: Function[];
/**
* Additional, extra models that should be inspected and included in the specification
*/
extraModels?: Function[];
/**
* If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
*/
ignoreGlobalPrefix?: boolean;
/**
* If `true`, swagger will also load routes from the modules imported by `include` modules
*/
deepScanRoutes?: boolean;
/**
* Custom operationIdFactory that will be used to generate the `operationId`
* based on the `controllerKey` and `methodKey`
* @default () => controllerKey_methodKey
*/
operationIdFactory?: (controllerKey: string, methodKey: string) => string;
}
Nous pouvons configurer les options comme ci-dessous :
const options: SwaggerDocumentOptions = {
deepScanRoutes: true
};
const document = SwaggerModule.createDocument(app, config, options);
5 – Options de configuration de l’interface utilisateur de NestJS Swagger
Une autre couche d’options de configuration est disponible. Nous pouvons passer un objet options appartenant à la classe ExpressSwaggerCustomOptions comme quatrième argument de la méthode SwaggerModule.setup().
Voir ci-dessous la définition de l’interface :
export interface ExpressSwaggerCustomOptions {
explorer?: boolean;
swaggerOptions?: Record<string, any>;
customCss?: string;
customCssUrl?: string;
customJs?: string;
customfavIcon?: string;
swaggerUrl?: string;
customSiteTitle?: string;
validatorUrl?: string;
url?: string;
urls?: Record<'url' | 'name', string>[];
}
Comme vous pouvez le voir, il existe de nombreuses options de configuration. Nous pouvons les utiliser comme ci-dessous :
const customOptions: SwaggerCustomOptions = {
customSiteTitle: 'Book API Docs'
}
SwaggerModule.setup('api', app, document, customOptions);
Cela changera essentiellement le titre du site dans l’onglet du navigateur.
Conclusion
Avec cela, nous avons appris avec succès la configuration de NestJS Swagger. Nous avons également examiné les options personnalisées au niveau du document et les options de personnalisation de l’interface utilisateur Swagger. Cependant, nos définitions d’API sont encore incomplètes et insuffisantes. Dans d’autres articles, nous verrons comment utiliser NestJS Swagger APIProperty et NestJS Swagger Operations pour décrire nos API d’une manière encore meilleure.
Si vous avez des commentaires ou des questions, n’hésitez pas à écrire dans la section commentaires ci-dessous.