Versioning
Le versionnement vous permet d’avoir différentes versions de vos contrôleurs ou routes individuelles fonctionnant au sein de la même application. Les applications changent très souvent et il n’est pas inhabituel qu’il y ait des modifications disruptives que vous devez apporter tout en ayant besoin de supporter la version précédente de l’application.
Il existe 4 types de versionnement qui sont pris en charge :
Type de versionnement | Description |
---|---|
URI Versioning | La version sera passée dans l’URI de la requête (par défaut) |
Header Versioning | Un en-tête de requête personnalisé spécifiera la version |
Media Type Versioning | L’en-tête Accept de la requête spécifiera la version |
Custom Versioning | Tout aspect de la requête peut être utilisé pour spécifier les versions. Une fonction personnalisée est fournie pour extraire ces versions. |
URI Versioning Type
Le versionnement URI utilise la version passée dans l’URI de la requête, comme https://example.com/v1/route
et https://example.com/v2/route
.
Pour activer le versionnement URI pour votre application, faites ceci :
main.tsconst app = await NestFactory.create(AppModule);// ou app.enableVersioning()app.enableVersioning({ type: VersioningType.URI,});await app.listen(3000);
Header Versioning Type
Le versionnement par en-tête utilise un en-tête de requête personnalisé, spécifié par l’utilisateur, pour spécifier la version où la valeur de l’en-tête sera la version à utiliser pour la requête.
Exemples de requêtes HTTP pour le versionnement par en-tête :
Pour activer le Header Versioning pour votre application, faites ceci :
main.tsconst app = await NestFactory.create(AppModule);app.enableVersioning({ type: VersioningType.HEADER, header: 'Custom-Header',});await app.listen(3000);
La propriété header
doit être le nom de l’en-tête qui contiendra la version de la requête.
Media Type Versioning Type
Le versionnement par type de média utilise l’en-tête Accept
de la requête pour spécifier la version.
Au sein de l’en-tête Accept
, la version sera séparée du type de média par un point-virgule ;
. Il devrait ensuite contenir une paire clé-valeur qui représente la version à utiliser pour la requête, comme Accept: application/json;v=2
. La clé est traitée plus comme un préfixe lors de la détermination de la version à configurer pour inclure la clé et le séparateur.
Pour activer le Media Type Versioning pour votre application, faites ceci :
main.tsconst app = await NestFactory.create(AppModule);app.enableVersioning({ type: VersioningType.MEDIA_TYPE, key: 'v=',});await app.listen(3000);
La propriété key
doit être la clé et le séparateur de la paire clé-valeur qui contient la version.
Custom Versioning Type
Le versionnement personnalisé utilise tout aspect de la requête pour spécifier la version (ou versions). La requête entrante est analysée en utilisant une fonction extractor
qui retourne une chaîne ou un tableau de chaînes.
Si plusieurs versions sont fournies par le demandeur, la fonction d’extraction peut retourner un tableau de chaînes, triées par ordre de la version la plus élevée à la plus basse. Les versions sont associées à des routes par ordre de la plus élevée à la plus basse.
Si une chaîne vide ou un tableau est retourné par l’extracteur, aucune route n’est associée et un 404 est retourné.
Par exemple, si une requête entrante spécifie qu’elle prend en charge les versions 1
, 2
, et 3
, la fonction extractor
DOIT retourner [3, 2, 1]
. Cela garantit que la version de route la plus élevée possible est sélectionnée en premier.
Si les versions [3, 2, 1]
sont extraites, mais que seules les versions 2
et 1
existent, la route correspondant à la version 2
est sélectionnée (la version 3
est automatiquement ignorée).
Pour activer le Custom Versioning pour votre application, créez une fonction extractor
et passez-la à votre application comme suit :
const extractor = (request: FastifyRequest): string | string[] => [request.headers['custom-versioning-field'] ?? ''] .flatMap(v => v.split(',')) .filter(v => !!v) .sort() .reverse();
const app = await NestFactory.create(AppModule);app.enableVersioning({ type: VersioningType.CUSTOM, extractor,});await app.listen(3000);
Usage
Le versionnement vous permet de versionner des contrôleurs, des routes individuelles, et fournit également un moyen pour certaines ressources de renoncer au versionnement. L’utilisation du versionnement est la même quelle que soit le type de versionnement utilisé par votre application.
Controller versions
Une version peut être appliquée à un contrôleur, définissant la version pour toutes les routes au sein du contrôleur.
Pour ajouter une version à un contrôleur, procédez comme suit :
cats.controller.ts@Controller({ version: '1',})export class CatsControllerV1 { @Get('cats') findAll(): string { return 'Cette action retourne tous les chats pour la version 1'; }}
Route versions
Une version peut être appliquée à une route individuelle. Cette version remplacera toute autre version qui pourrait affecter la route, comme la version du contrôleur.
Pour ajouter une version à une route individuelle, procédez comme suit :
cats.controller.tsimport { Controller, Get, Version } from '@nestjs/common';
@Controller()export class CatsController { @Version('1') @Get('cats') findAllV1(): string { return 'Cette action retourne tous les chats pour la version 1'; }
@Version('2') @Get('cats') findAllV2(): string { return 'Cette action retourne tous les chats pour la version 2'; }}
Multiple versions
Plusieurs versions peuvent être appliquées à un contrôleur ou une route. Pour utiliser plusieurs versions, vous devez définir la version comme un tableau.
Pour ajouter plusieurs versions, procédez comme suit :
cats.controller.ts@Controller({ version: ['1', '2'],})export class CatsController { @Get('cats') findAll(): string { return 'Cette action retourne tous les chats pour la version 1 ou 2'; }}
Version “Neutral”
Certaines contrôleurs ou routes peuvent ne pas se soucier de la version et auraient la même fonctionnalité indépendamment de la version. Pour cela, la version peut être définie sur le symbole VERSION_NEUTRAL
.
Une requête entrante sera mappée à un contrôleur ou une route VERSION_NEUTRAL
peu importe la version envoyée dans la requête en plus du fait que si la requête ne contient pas de version.
Pour ajouter un contrôleur ou une route neutre en version, procédez comme suit :
cats.controller.tsimport { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';
@Controller({ version: VERSION_NEUTRAL,})export class CatsController { @Get('cats') findAll(): string { return 'Cette action retourne tous les chats indépendamment de la version'; }}
Global default version
Si vous ne souhaitez pas fournir de version pour chaque contrôleur ou chaque route individuelle, ou si vous souhaitez avoir une version spécifique définie comme version par défaut pour chaque contrôleur/route qui n’a pas de version spécifiée, vous pouvez définir la defaultVersion
comme suit :
app.enableVersioning({ // ... defaultVersion: '1', // ou defaultVersion: ['1', '2'], // ou defaultVersion: VERSION_NEUTRAL,});
Middleware versioning
Les middlewares peuvent également utiliser des métadonnées de versionnement pour configurer le middleware pour une version de route spécifique. Pour ce faire, fournissez le numéro de version comme l’un des paramètres de la méthode MiddlewareConsumer.forRoutes()
:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';import { LoggerMiddleware } from './common/middleware/logger.middleware';import { CatsModule } from './cats/cats.module';import { CatsController } from './cats/cats.controller';
@Module({ imports: [CatsModule],})export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LoggerMiddleware) .forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' }); }}
Avec le code ci-dessus, le LoggerMiddleware
ne sera appliqué qu’à la version ‘2’ du point de terminaison /cats
.