Share via


Tutoriel : Générer un client d’API REST

Une application qui utilise une API REST est un scénario très courant. En règle générale, vous devez générer du code client que votre application peut utiliser pour appeler l’API REST. Dans ce tutoriel, vous allez apprendre à générer automatiquement le client d’API REST pendant le processus de build à l’aide de MSBuild. Vous allez utiliser NSwag, un outil qui génère du code client pour une API REST.

L’exemple de code complet est disponible dans génération du client d’API REST dans le référentiel d’exemples .NET sur GitHub.

L’exemple montre une application console qui consomme l’API Pet Store publique, qui publie une spécification OpenAPI.

Le tutoriel suppose une connaissance de base des termes MSBuild tels que les tâches, les cibles, les propriétés ou les runtimes. Pour obtenir le contexte nécessaire, consultez l’article Concepts MSBuild.

Lorsque vous souhaitez exécuter un outil en ligne de commande dans le cadre d’une build, il existe deux approches à prendre en compte. La première consiste à utiliser la tâche MSBuild Exec, qui vous permet d’exécuter un outil en ligne de commande et de spécifier ses paramètres. L’autre méthode consiste à créer une tâche personnalisée dérivée de ToolTask, ce qui vous donne un meilleur contrôle.

Prérequis

Vous devez avoir une compréhension des concepts MSBuild tels que les tâches, les cibles et les propriétés. Consultez Concepts MSBuild.

Les exemples nécessitent MSBuild, qui est installé avec Visual Studio, mais qui peut également être installé séparément. Consultez Télécharger MSBuild sans Visual Studio.

Option 1 : tâche Exec

La tâche Exec appelle simplement le processus spécifié avec les arguments spécifiés, attend qu’il se termine, puis retourne true si le processus s’est terminé avec succès ou false si une erreur s’est produite.

La génération de code NSwag peut être utilisée à partir de MSBuild ; consultez NSwag.MSBuild.

Le code complet se trouve dans le dossier PetReaderExecTaskExample ; vous pouvez le télécharger et y jeter un coup d’œil. Ce tutoriel vous guidera pas-à-pas pour vous apprendre les concepts.

  1. Créer une nouvelle application console appelée PetReaderExecTaskExample. Utilisez .NET 6.0 ou version ultérieure.

  2. Créez un autre projet dans la même solution : PetShopRestClient (Cette solution va contenir le client généré en tant que bibliothèque). Pour ce projet, utilisez .NET Standard 2.1. Le client généré ne se compile pas sur .NET Standard 2.0.

  3. Dans le projet PetReaderExecTaskExample, ajoutez une dépendance de projet au projet PetShopRestClient.

  4. Dans le projet PetShopRestClient, incluez les packages NuGet suivants :

    • Nswag.MSBuild, qui permet d’accéder au générateur de code à partir de MSBuild
    • Newtonsoft.Json, nécessaire pour compiler le client généré
    • System.ComponentModel.Annotations, nécessaire pour compiler le client généré
  5. Dans le projet PetShopRestClient, ajoutez un dossier (nommé PetShopRestClient) pour la génération de code et supprimez le Class1.cs généré automatiquement.

  6. Créez un fichier texte nommé petshop-openapi-spec.json à la racine du projet. Copiez la spécification OpenApi à partir d’ici et enregistrez-la dans le fichier. Il est préférable de copier un instantané de la spécification au lieu de la lire en ligne pendant la build. Vous souhaitez toujours une build reproductible de manière cohérente qui dépend uniquement de l’entrée. La consommation directe de l’API peut transformer une build qui fonctionne aujourd’hui en une build qui échoue demain à partir de la même source. L’instantané enregistré sur petshop-openapi-spec.json nous permet d’avoir toujours une version qui est générée même si la spécification change.

  7. Ensuite, modifiez PetShopRestClient.csproj et ajoutez une cible MSBuild pour générer le client pendant le processus de build.

    Tout d’abord, ajoutez quelques propriétés utiles pour la génération du client :

     <PropertyGroup>
         <PetOpenApiSpecLocation>petshop-openapi-spec.json</PetOpenApiSpecLocation>
         <PetClientClassName>PetShopRestClient</PetClientClassName>
         <PetClientNamespace>PetShopRestClient</PetClientNamespace>
         <PetClientOutputDirectory>PetShopRestClient</PetClientOutputDirectory>
     </PropertyGroup>
    

    Ajoutez les cibles suivantes :

     <Target Name="generatePetClient" BeforeTargets="CoreCompile" Inputs="$(PetOpenApiSpecLocation)" Outputs="$(PetClientOutputDirectory)\$(PetClientClassName).cs">
         <Exec Command="$(NSwagExe) openapi2csclient /input:$(PetOpenApiSpecLocation)  /classname:$(PetClientClassName) /namespace:$(PetClientNamespace) /output:$(PetClientOutputDirectory)\$(PetClientClassName).cs" ConsoleToMSBuild="true">
         <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
       </Exec>
     </Target>
     <Target Name="forceReGenerationOnRebuild" AfterTargets="CoreClean">
        <Delete Files="$(PetClientOutputDirectory)\$(PetClientClassName).cs"></Delete>
     </Target>
    

    Notez que cette cible utilise les attributs BeforeTarget et AfterTarget pour définir l’ordre des builds. La première cible appelée generatePetClient sera exécutée avant la cible de compilation principale, de sorte que la source sera créée avant l’exécution du compilateur. Les paramètres d’entrée et de sortie sont liés à la génération incrémentielle. MSBuild peut comparer les timestamps des fichiers d’entrée avec ceux des fichiers de sortie et déterminer s’il faut ignorer, générer ou regénérer partiellement une cible.

    Après avoir installé le package NuGet NSwag.MSBuild dans votre projet, vous pouvez utiliser la variable $(NSwagExe) dans votre fichier .csproj pour exécuter l’outil en ligne de commande NSwag dans une cible MSBuild. De cette façon, les outils peuvent facilement être mis à jour via NuGet. Ici, vous utilisez la tâche MSBuild Exec pour exécuter le programme NSwag avec les paramètres requis pour générer l’API Rest cliente. Consultez Commande et paramètres NSwag.

    Vous pouvez capturer la sortie à partir de <Exec> l’ajout de ConsoleToMsBuild="true" à votre balise <Exec>, puis de la capture de la sortie à l’aide du paramètre ConsoleOutput dans une balise <Output>. ConsoleOutput retourne le résultat en tant que Item. L’espace blanc est réduit. ConsoleOutput est activé lorsque ConsoleToMSBuild a la valeur true.

    La deuxième cible appelée forceReGenerationOnRebuild supprime la classe générée pendant le nettoyage pour forcer la régénération du code généré lors de l’exécution de la cible de regénération. Cette cible s’exécute après la cible MSBuild prédéfinie CoreClean.

  8. Exécutez la regénération d’une solution Visual Studio et consultez le client généré dans le dossier PetShopRestClient.

  9. Utilisez maintenant le client généré. Accédez au client Program.cs, puis copiez le code suivant :

    using System;
    using System.Net.Http;
    
    namespace PetReaderExecTaskExample
    {
       internal class Program
       {
           private const string baseUrl = "https://petstore.swagger.io/v2";
           static void Main(string[] args)
           {
               HttpClient httpClient = new HttpClient();
               httpClient.BaseAddress = new Uri(baseUrl);
               var petClient = new PetShopRestClient.PetShopRestClient(httpClient);
               var pet = petClient.GetPetByIdAsync(1).Result;
               Console.WriteLine($"Id: {pet.Id} Name: {pet.Name} Status: {pet.Status} CategoryName: {pet.Category.Name}");
           }
       }
    }
    

    Notes

    Ce code utilise new HttpClient() parce qu’il est simple à démontrer, mais ce n’est pas la meilleure pratique pour le code réel. La meilleure pratique consiste à utiliser HttpClientFactory pour créer un objet HttpClient qui résout les problèmes connus de requête HttpClient tels que l’épuisement des ressources ou les problèmes DNS obsolètes. Consultez Utiliser IHttpClientFactory pour implémenter des requêtes HTTP résilientes.

Félicitations ! Vous pouvez maintenant exécuter le programme pour voir comment il fonctionne.

Option 2 : tâche personnalisée dérivée de ToolTask

Dans de nombreux cas, l’utilisation de la tâche Exec est suffisante pour exécuter un outil externe pour effectuer quelque chose comme la génération de code client de l’API REST, mais que se passe-t-il si vous souhaitez autoriser la génération de code client de l’API REST si et uniquement si vous n’utilisez pas un chemin Windows absolu comme entrée ? Ou que se passe-t-il si vous devez calculer d’une manière ou d’une autre l’emplacement de l’exécutable ? Lorsqu’il est nécessaire d’exécuter du code pour effectuer un travail supplémentaire, la tâche d’outil MSBuild est la meilleure solution. La classe ToolTask est une classe abstraite dérivée de MSBuild Task. Vous pouvez définir une sous-classe concrète, qui crée une tâche MSBuild personnalisée. Cette approche vous permet d’exécuter n’importe quel code nécessaire pour préparer l’exécution des commandes. Vous devez d’abord lire le tutoriel Créer une tâche personnalisée pour la génération de code .

Vous allez créer une tâche personnalisée dérivée de MSBuild ToolTask qui générera un client d’API REST, mais elle sera conçue pour émettre une erreur si vous essayez de référencer la spécification OpenApi à l’aide d’une adresse HTTP. NSwag prend en charge une adresse HTTP en tant qu’entrée de spécification OpenApi, mais pour les besoins de cet exemple, supposons qu’il existe une exigence de conception pour l’interdire.

Le code complet se trouve dans ce dossier PetReaderToolTaskExample ; vous pouvez le télécharger et y jeter un coup d’œil. Ce tutoriel vous guidera pas-à-pas pour vous apprendre certains concepts que vous pouvez appliquer à vos propres scénarios.

  1. Créez un projet Visual Studio pour la tâche personnalisée. Appelez-le RestApiClientGenerator et utilisez le modèle Bibliothèque de classes (C#) avec .NET Standard 2.0. Nommez la solution PetReaderToolTaskExample.

  2. Supprimez Class1.cs, qui a été généré automatiquement.

  3. Ajouter les packages NuGet Microsoft.Build.Utilities.Core :

    • Créez une classe appelée RestApiClientGenerator.

    • Héritez de MSBuild ToolTask et implémentez la méthode abstraite comme indiqué dans le code suivant :

      using Microsoft.Build.Utilities;
      
      namespace RestApiClientGenerator
      {
          public class RestApiClientGenerator : ToolTask
          {
              protected override string ToolName => throw new System.NotImplementedException();
      
              protected override string GenerateFullPathToTool()
              {
                  throw new System.NotImplementedException();
              }
          }
      }
      
  4. Ajoutez les paramètres suivants :

    • InputOpenApiSpec, où la spécification est
    • ClientClassName, nom de la classe générée
    • ClientNamespaceName, espace de noms où la classe est générée
    • FolderClientClass, chemin du dossier où se trouve la classe
    • NSwagCommandFullPath, chemin d’accès complet au répertoire où se trouve NSwag.exe
         [Required]
         public string InputOpenApiSpec { get; set; }
         [Required]
         public string ClientClassName { get; set; }
         [Required]
         public string ClientNamespaceName { get; set; }
         [Required]
         public string FolderClientClass { get; set; }
         [Required]
         public string NSwagCommandFullPath { get; set; }
    
  5. Installez l’outil en ligne de commande NSwag. Vous aurez besoin du chemin d’accès complet au répertoire où se trouve NSwag.exe.

  6. Implémentez les méthodes abstraites :

       protected override string ToolName => "RestApiClientGenerator";
    
       protected override string GenerateFullPathToTool()
       {
           return $"{NSwagCommandFullPath}\\NSwag.exe";
       }
    
  7. Il existe de nombreuses méthodes que vous pouvez remplacer. Pour l’implémentation actuelle, définissez ces deux éléments :

    • Définissez le paramètre de commande :
      protected override string GenerateCommandLineCommands()
      {
          return $"openapi2csclient /input:{InputOpenApiSpec}  /classname:{ClientClassName} /namespace:{ClientNamespaceName} /output:{FolderClientClass}\\{ClientClassName}.cs";
      }
    
    • Validation de paramètre :
    protected override bool ValidateParameters()
    {
          //http address is not allowed
          var valid = true;
          if (InputOpenApiSpec.StartsWith("http:") || InputOpenApiSpec.StartsWith("https:"))
          {
              valid = false;
              Log.LogError("URL is not allowed");
          }
    
          return valid;
    }
    

    Notes

    Cette validation simple peut être effectuée d’une autre manière sur le fichier MSBuild, mais il est recommandé de le faire dans du code C# et d’encapsuler la commande et la logique.

  8. Créez le projet.

Créer une application console pour utiliser la nouvelle tâche MSBuild

L’étape suivante consiste à créer une application qui utilise la tâche.

  1. Créez un projet d’application console et appelez-le PetReaderToolTaskConsoleApp. Choisissez .NET 6.0. Marquez-le comme projet de démarrage.

  2. Créez un projet bibliothèque de classes pour générer le code, appelé PetRestApiClient. Utilisez .NET Standard 2.1.

  3. Dans le projet PetReaderToolTaskConsoleApp, créez une dépendance de projet à PetRestApiClient.

  4. Dans le projet PetRestApiClient, créez un dossier PetRestApiClient. Ce dossier contient le code généré.

  5. Supprimez Class1.cs, qui a été généré automatiquement.

  6. Sur PetRestApiClient, ajoutez les packages NuGet suivants :

    • Newtonsoft.Json, nécessaire pour compiler le client généré
    • System.ComponentModel.Annotations, nécessaire pour compiler le client généré
  7. Dans le projet PetRestApiClient, créez un fichier texte nommé petshop-openapi-spec.json (dans le dossier du projet). Pour ajouter la spécification OpenApi, copiez le contenu à partir d’ici dans le fichier. Nous aimons une build reproductible qui dépend uniquement de l’entrée, comme indiqué précédemment. Dans cet exemple, vous allez générer une erreur de build si un utilisateur choisit une URL comme entrée de spécification OpenApi.

    Important

    Une regénération générale ne fonctionnera pas. Vous verrez des erreurs qui indiquent qu’il n’est pas en mesure de copier ou de supprimer RestApiClientGenerator.dll’ . Cela est dû au fait qu’il tente de générer la tâche personnalisée MBuild dans le même processus de génération qui l’utilise. Sélectionnez PetReaderToolTaskConsoleApp et régénérez uniquement ce projet. L’autre solution consiste à placer la tâche personnalisée dans une solution Visual Studio complètement indépendante, comme vous l’avez fait dans l’exemple du Tutoriel : Créer une tâche personnalisée .

  8. Copiez le code suivant dans Program.cs :

     using System;
     using System.Net.Http;
     namespace PetReaderToolTaskConsoleApp
     {
       internal class Program
       {
           private const string baseUrl = "https://petstore.swagger.io/v2";
           static void Main(string[] args)
           {
               HttpClient httpClient = new HttpClient();
               httpClient.BaseAddress = new Uri(baseUrl);
               var petClient = new PetRestApiClient.PetRestApiClient(httpClient);
               var pet = petClient.GetPetByIdAsync(1).Result;
               Console.WriteLine($"Id: {pet.Id} Name: {pet.Name} Status: {pet.Status} CategoryName: {pet.Category.Name}");
           }
       }
     }
    
  9. Modifiez les instructions MSBuild pour appeler la tâche et générer le code. Modifiez PetRestApiClient.csproj en procédant comme suit :

    1. Inscrivez l’utilisation de la tâche personnalisée MSBuild :

      <UsingTask TaskName="RestApiClientGenerator.RestApiClientGenerator" AssemblyFile="..\RestApiClientGenerator\bin\Debug\netstandard2.0\RestApiClientGenerator.dll" />
      
    2. Ajoutez quelques propriétés nécessaires pour exécuter la tâche :

       <PropertyGroup>
          <!--The place where the OpenApi spec is in-->
         <PetClientInputOpenApiSpec>petshop-openapi-spec.json</PetClientInputOpenApiSpec>
         <PetClientClientClassName>PetRestApiClient</PetClientClientClassName>
         <PetClientClientNamespaceName>PetRestApiClient</PetClientClientNamespaceName>
         <PetClientFolderClientClass>PetRestApiClient</PetClientFolderClientClass>
         <!--The directory where NSawg.exe is in-->
         <NSwagCommandFullPath>C:\Nsawg\Win</NSwagCommandFullPath>
        </PropertyGroup>
      

      Important

      Sélectionnez la valeur NSwagCommandFullPath appropriée en fonction de l’emplacement d’installation sur votre système.

    3. Ajoutez une cible MSBuild pour générer le client pendant le processus de génération. Cette cible doit s’exécuter avant l’exécution de CoreCompile pour générer le code utilisé dans la compilation.

      <Target Name="generatePetClient" BeforeTargets="CoreCompile" Inputs="$(PetClientInputOpenApiSpec)" Outputs="$(PetClientFolderClientClass)\$(PetClientClientClassName).cs">
        <!--Calling our custom task derivated from MSBuild Tool Task-->
        <RestApiClientGenerator InputOpenApiSpec="$(PetClientInputOpenApiSpec)" ClientClassName="$(PetClientClientClassName)" ClientNamespaceName="$(PetClientClientNamespaceName)" FolderClientClass="$(PetClientFolderClientClass)" NSwagCommandFullPath="$(NSwagCommandFullPath)"></RestApiClientGenerator>
      </Target>
      
      <Target Name="forceReGenerationOnRebuild" AfterTargets="CoreClean">
        <Delete Files="$(PetClientFolderClientClass)\$(PetClientClientClassName).cs"></Delete>
      </Target>
      

    Input et Output sont liés à la génération incrémentielle, et la cible forceReGenerationOnRebuild supprime le fichier généré après CoreClean, ce qui force le client à être régénéré pendant l’opération de regénération.

  10. Sélectionnez PetReaderToolTaskConsoleApp et régénérez uniquement ce projet. À présent, le code client est généré et le code est compilé. Vous pouvez l’exécuter et voir son fonctionnement. Ce code génère le code à partir d’un fichier, et cela est autorisé.

  11. Dans cette étape, vous allez démontrer la validation des paramètres. Dans PetRestApiClient.csproj, modifiez la propriété $(PetClientInputOpenApiSpec) pour utiliser l’URL :

      <PetClientInputOpenApiSpec>https://petstore.swagger.io/v2/swagger.json</PetClientInputOpenApiSpec>
    
  12. Sélectionnez PetReaderToolTaskConsoleApp et régénérez uniquement ce projet. Vous obtiendrez l’erreur « L’URL n’est pas autorisée » conformément aux exigences de conception.

Téléchargement du code

Installez l’outil en ligne de commande NSwag. Vous aurez besoin du chemin d’accès complet au répertoire où se trouve NSwag.exe. Après cela, modifiez PetRestApiClient.csproj et sélectionnez la valeur $(NSwagCommandFullPath) appropriée en fonction du chemin d’installation sur votre ordinateur. À présent, sélectionnez RestApiClientGenerator et générez uniquement ce projet, puis sélectionnez et régénérez PetReaderToolTaskConsoleApp. Vous pouvez exécuter PetReaderToolTaskConsoleApp pour vérifier que tout fonctionne comme prévu.

Étapes suivantes

Vous souhaiterez peut-être publier votre tâche personnalisée en tant que package NuGet.

Vous pouvez également découvrir comment tester une tâche personnalisée.