Fermer

juin 16, 2021

Votre guide sur la gestion des versions des API REST dans ASP.NET Core


Depuis ASP.NET Core 3.1, vous avez la possibilité de versionner vos API à l'aide d'un package Microsoft NuGet. Apprenez à utiliser ce package pour versionner facilement vos API.

Lorsque vous envoyez une API, vous invitez les développeurs à l'utiliser sur la base d'un contrat convenu. Alors que se passe-t-il si le contrat change ? Regardons un exemple simple.

Si j'appelle une API avec une URL de https://mybandapi.com/api/bands/4j'obtiens la réponse suivante :

 {
   "id": 4,
   "nom": "Les Aigles, mec"
}

Maintenant, disons que je décide de mettre à jour mon schéma d'API avec un nouveau champ, YearFounded. Voici à quoi ressemble la nouvelle réponse maintenant :

{
   "id": 4,
   "name": "The Eagles, man"[19659006],
   "Année de fondation" : 1971
}

Avec ce nouveau champ, les clients existants continuent de fonctionner. C'est un changement ininterrompu, car les applications existantes peuvent l'ignorer avec plaisir. Vous devriez documenter le nouveau champ dans The Long Run, bien sûr, mais ce n'est pas une grosse affaire à la fin de la journée.

Disons que vous voulez que le nom soit plutôt une collection de noms associés au groupe, comme ceci :

{
   "id": 4,
   "noms": 
    [
     "Les Aigles, mec",
     "Les Aigles"
   ],
   "Fondation": 1971
}

Vous avez introduit un changement de rupture. Vos consommateurs s'attendaient à ce que le champ name soit une valeur de chaîne, et maintenant vous retournez une collection de chaînes. Par conséquent, lorsque les consommateurs appellent l'API, leurs applications ne fonctionneront pas comme prévu et vos utilisateurs ne vont pas y aller doucement.

Qu'il s'agisse d'un petit changement permanent ou d'un changement qui casse des choses, vos consommateurs doivent savoir à quoi s'attendre. Pour vous aider à gérer vos API évolutives, vous aurez besoin d'une stratégie de gestion des versions d'API.

Depuis ASP.NET Core 3.1, Microsoft a fourni des bibliothèques pour faciliter la gestion des versions d'API. Ils fournissent un moyen simple et puissant d'ajouter une sémantique de gestion des versions à vos services REST et sont également conformes aux Directives REST de Microsoft.

Dans cet article, je vais vous montrer comment utiliser le ]Microsoft.AspNetCore.Mvc.Versioning Package NuGet pour appliquer la gestion des versions d'API aux API Web REST ASP.NET Core.

Nous allons examiner différentes approches de la gestion des versions de vos API et comment vous pouvez activer la fonctionnalité dans ASP.NET Core. Quelle approche devriez-vous utiliser? Comme toujours, It Depends™. Il n'y a pas d'approche dogmatique « taille unique » pour la gestion des versions d'API. Au lieu de cela, utilisez l'approche qui convient le mieux à votre situation.

Get Started

Pour commencer, vous devrez récupérer le package Microsoft.AspNetCore.Mvc.Versioning NuGet. Le moyen le plus simple consiste à utiliser l'interface de ligne de commande .NET. Exécutez la commande suivante à partir du répertoire de votre projet :

dotnet add package Microsoft.AspNetCore.Mvc.Versioning

Avec le package installé dans votre projet, vous devrez ajouter le service au conteneur d'injection de dépendance d'ASP.NET Core. À partir de Startup.ConfigureServicesajoutez ce qui suit :

public void ConfigureServices(IServiceCollection services)
{
   services.AddApiVersioning();
   
}

Que se passe-t-il lorsque je fais une demande GET sur https://mybandapi.com/api/ bandes/4? Je suis accueilli avec la réponse suivante 400 Bad Request :

{
    "error": {
        "code": " ApiVersionUnspecified",
        "message": "Une version API est requise, mais n'a pas été spécifiée.",
        "innerError": null 
    }
}

Par défaut, vous devez ajouter ?api-request=1.0 à l'URL pour que cela fonctionne, comme ceci :

https://mybandapi. com/api/bands/4?api-request=1.0

Ce n'est pas une excellente expérience de développeur. Pour vous aider, nous pouvons introduire une version par défaut. Si les consommateurs n'incluent pas explicitement une version dans leur demande, nous supposerons qu'ils souhaitent utiliser la version 1.0. Notre bibliothèque prend un type ApiVersioningOptionsque nous pouvons utiliser pour spécifier une version par défaut. Vous dites donc aux consommateurs : « Si vous n'optez pas pour une autre version, vous utiliserez la version 1.0 de notre API. »

Dans Startup.ConfigureServicesmettez à jour votre Ajoutez le codeApiVersioning à ceci :

services.AjoutezApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
}[19659006]);

Avec cela, vos consommateurs devraient pouvoir appeler une version par défaut à partir de https://mybandapi.com/api/bands/4.

Présentation Plusieurs versions pour un seul point de terminaison

Disons que nous voulons travailler avec deux versions de notre API, 1.0 et 2.0. Nous pouvons l'utiliser en décorant notre contrôleur avec un ApiVersionAttribute.

[Produces("application/json")][19659012][Route("api/[contrôleur]")]
[ApiVersion("1.0" )]
[ApiVersion("2.0")]
public class BandsController : ContrôleurBase
{}

Une fois que je fais cela, je peux utiliser le MapToApiVersionAttribute pour indiquer à ASP.NET Core quelles méthodes d'action sont mappées à mes versions d'API. Dans mon cas, j'ai deux méthodes connectées à un GET sur api/bandsGetById et GetById20.

Voici à quoi ressemblent les annotations :

[MapVersApiVersion("1.0")]
[HttpGet("{id}" )]
public async Tâche<ActionResult<Band>> GetById[19659006](int id)
{}
    
[MapVersApiVersion("2.0")][19659012][HttpGet("{id}")]
public async Tâche<ActionResult< Band>> GetById20(int id)
{}

Avec cela, le contrôleur exécutera e La version 1.0 de GetById avec l'URI normal (ou /api/bands/4?api-version=1.0) et le contrôleur exécute la version 2.0 lorsque le consommateur utilise https://mybandapi.com/api/bands/4?api-version=2.0.

Maintenant que nous prenons en charge plusieurs versions, c'est une bonne idée d'informer vos clients des versions de vos points de terminaison. justificatif. Pour ce faire, vous pouvez utiliser le code suivant pour signaler les versions d'API au client.

services.AddApiVersioning(options =>
{ 
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
});

Lorsque vous faites cela, ASP.NET Core fournit un api-supported-versions en-tête de réponse qui indique les versions prises en charge par un point de terminaison.

Le noyau ASP.NET renvoie un

Par défaut, la bibliothèque prend en charge la gestion des versions à partir des chaînes de requête. J'aime cette méthode. Vos clients peuvent opter pour de nouvelles versions lorsqu'ils sont prêts. Et si aucune version n'est spécifiée, les consommateurs peuvent se fier à la version par défaut.

Bien sûr, ce n'est pas la seule façon de versionner une API. En plus des chaînes de requête, nous examinerons d'autres façons de versionner vos API dans ASP.NET Core :

  • chemin URI/URL
  • En-têtes de requête personnalisés
  • Versionnement des médias avec les en-têtes Accept

Versioning With a Chemin URI

Si je veux versionner avec le schéma familier /api/v{version number}je peux le faire facilement. Ensuite, depuis le haut de mon contrôleur, je peux utiliser un RouteAttribute qui correspond à ma version d'API. Voici à quoi ressemblent mes annotations de contrôleur maintenant :

[ApiVersion("1.0")]
[ApiVersion([19659111]"2.0")]
[Route("api/v{version:apiVersion}/[contrôleur]")] 
public class BandsController : ControllerBase
{}

Ensuite, lorsque j'appellerai mon API depuis api/v2/bands/4j'appellerai la version 2 de mon API. Bien qu'il s'agisse d'une méthode populaire et facile à mettre en place, elle ne va pas sans inconvénients. Cela n'implique pas une version par défaut, donc les clients peuvent se sentir obligés de mettre à jour les URI dans leurs applications chaque fois qu'un changement se produit.

Que ce soit en utilisant une chaîne de requête ou le chemin d'URI, Microsoft.AspNetCore.Mvc.Versioning facilite l'utilisation de la gestion des versions à partir du niveau URI. De nombreux clients peuvent préférer supprimer la gestion des versions d'URI pour diverses raisons. Dans ces cas, vous pouvez utiliser des en-têtes.

Si vous souhaitez laisser vos URI seuls, vous pouvez demander aux consommateurs de transmettre une version à partir d'un en-tête de requête. Par exemple, si les consommateurs souhaitent utiliser une version autre que celle par défaut de mon API, je peux leur faire transmettre une valeur d'en-tête de demande X-Api-Version.

Lors du passage aux en-têtes, tenez également compte de cela. vous compliquez un peu l'accès à l'API. Au lieu d'atteindre un URI, les clients doivent atteindre vos points de terminaison par programme ou à partir d'outils d'API. Ce n'est peut-être pas un énorme saut pour vos clients, mais c'est quelque chose à considérer.

Pour utiliser des en-têtes de requête personnalisés, vous pouvez définir le ApiVersionReader de la bibliothèque sur un HeaderApiVersionReaderpuis passer dans le nom de l'en-tête. (Si vous voulez gagner Trivia Night au pub, la réponse à "Quelle est la valeur par défaut ApiVersionReader ?" est "QueryStringApiVersionReader.")

services.[19659060]Ajouter une version d'Api(options =>
{
   options.DefaultApiVersion = new ApiVersion(2, 0);
   options.AssumeDefaultVersionWhenUnspecified = true;
   options.RapportApiVersions = true;
   options.ApiVersionReader = nouveau En-têteApiVersionReader("X-Api-Version");
} );

Dans mon outil de test d'API, je peux transmettre une valeur X-Api-Version pour m'assurer que cela fonctionne. Et c'est le cas.

Un client transmet une version à l'en-tête de la requête

Lorsqu'un client vous transmet une requête, il utilise un en-tête Accept pour contrôler le format de la demande qu'il peut traiter. De nos jours, la valeur Accept la plus courante est le type de support application/json. Nous pouvons également utiliser la gestion des versions avec nos types de médias.

Pour activer cette fonctionnalité, remplacez AddApiVersioning par :

services.AddApiVersioning( options =>
{
     options.DefaultApiVersion = new ApiVersion(1, 0);
     options.AssumeDefaultVersionWhenUnspecified = true;
     options.RapportApiVersions = true;
     options.ApiVersionReader = nouveau MediaTypeApiVersionReader("v");
}) ;

Les clients peuvent ensuite transmettre une version API avec un en-tête Acceptcomme suit.

Passer une version API avec l'en-tête média

Combining Multiple Approaches

Quand en travaillant avec le package NuGet Microsoft.AspNetCore.Mvc.Versioningvous n'êtes pas obligé d'utiliser une seule méthode de gestion des versions. Par exemple, vous pouvez autoriser les clients à choisir entre transmettre une chaîne de requête ou un en-tête de requête. ApiVersionReader prend en charge une méthode statique Combine qui vous permet de spécifier plusieurs façons de lire les versions.

services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.RapportApiVersions = true;
    options.ApiVersionReader =
    ApiVersionReader.Combine(
       nouveau En-têteApiVersionReader("X-Api-Version"),
       nouveau  QueryStringApiVersionReader("version"));
});

Avec ceci en place, les clients obtiennent la v2.0 de notre API en appelant /api/bands/4?version=2 ou en spécifiant une valeur d'en-tête X-Api-Version de 2.

En savoir plus[19659052]Ce message ne fait qu'effleurer la surface. Vous pouvez faire tellement plus avec le package Microsoft.AspNetCore.Mvc.Versioning NuGet. Par exemple, vous pouvez travailler avec OData et activer un explorateur d'API versionnévous permettant d'ajouter une documentation versionnée à vos services. Si vous n'aimez pas décorer vos contrôleurs et méthodes avec des attributs, vous pouvez utiliser l'approche des conventions des contrôleurs .

Consultez la documentation de la bibliothèque pour plus de détailset assurez-vous de lire sur limitations connues (surtout si vous avez des considérations avancées de routage ASP.NET Core).




Source link