Condividi tramite


Esercitazione: Generare un client API REST

Un'applicazione che usa un'API REST è uno scenario molto comune. In genere, è necessario generare codice client che l'applicazione può usare per chiamare l'API REST. In questa esercitazione si apprenderà come generare automaticamente il client API REST durante il processo di compilazione usando MSBuild. Si userà NSwag, uno strumento che genera codice client per un'API REST.

Il codice di esempio completo è disponibile nella sezione generazione del client dell'API REST nel repository di esempi .NET su GitHub.

L'esempio mostra un'applicazione console che sfrutta l'API pubblica Pet Store, che pubblica una specifica OpenAPI .

L'esercitazione presuppone una conoscenza basilare dei termini di MSBuild, come attività, destinazioni, proprietà o runtime; per le informazioni generali necessarie, vedere l'articolo , Concetti relativi a MSBuild,.

Quando si vuole eseguire uno strumento da riga di comando come parte di una compilazione, esistono due approcci da considerare. Uno consiste nell'usare l'attività MSBuild Exec, che consente di eseguire uno strumento da riga di comando e di specificare i relativi parametri. L'altro metodo consiste nel creare un'attività personalizzata derivata da ToolTask, che offre un maggiore controllo.

Prerequisiti

È necessario avere una conoscenza dei concetti di MSBuild, ad esempio attività, destinazioni e proprietà. Vedere concetti relativi a MSBuild.

Gli esempi richiedono MSBuild, installato con Visual Studio, ma possono anche essere installati separatamente. Vedere Scaricare MSBuild senza Visual Studio.

Opzione 1: Esegui attività

L'attività Exec richiama semplicemente il processo specificato con gli argomenti specificati, attende il completamento e quindi restituisce true se il processo viene completato correttamente e false se si verifica un errore.

La generazione di codice NSwag può essere usata da MSBuild; vedere NSwag.MSBuild.

Il codice completo si trova nella cartella PetReaderExecTaskExample; è possibile scaricare e dare un'occhiata. In questa esercitazione si esamineranno passo dopo passo e si apprenderanno i concetti man mano.

  1. Creare una nuova applicazione console denominata PetReaderExecTaskExample. Usare .NET 6.0 o versione successiva.

  2. Creare un altro progetto nella stessa soluzione: PetShopRestClient (questa soluzione conterrà il client generato come libreria). Per questo progetto, usare .NET Standard 2.1. Il client generato non viene compilato in .NET Standard 2.0.

  3. Nel progetto PetReaderExecTaskExample, aggiungere una dipendenza dal progetto PetShopRestClient.

  4. Nel progetto PetShopRestClient includere i pacchetti NuGet seguenti:

    • Nswag.MSBuild, che consente l'accesso al generatore di codice da MSBuild
    • Newtonsoft.Json, necessario per compilare il client generato
    • System.ComponentModel.Annotations, necessario per compilare il client generato
  5. Nel progetto PetShopRestClient aggiungere una cartella (denominata PetShopRestClient) per la generazione del codice ed eliminare il Class1.cs generato automaticamente.

  6. Creare un file di testo denominato petshop-openapi-spec.json nella radice del progetto. Copiare la specifica OpenAPI da qui e salvarla nel file. È consigliabile copiare uno snapshot della specifica invece di leggerlo online durante la compilazione. Si vuole sempre una compilazione riproducibile coerente che dipende solo dall'input. L'uso diretto dell'API potrebbe trasformare una compilazione che funziona oggi in una compilazione che ha esito negativo domani dalla stessa origine. Lo snapshot memorizzato in petshop-openapi-spec.json ci consentirà di avere ancora una versione che si compila anche se la specifica cambia.

  7. Successivamente, modifica PetShopRestClient.csproj e aggiungi un target MSBuild per generare il client durante il processo di compilazione.

    Aggiungere prima di tutto alcune proprietà utili per la generazione del client:

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

    Aggiungere le destinazioni seguenti:

     <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>
    

    Si noti che questa destinazione usa gli attributi BeforeTarget e AfterTarget come modo per definire l'ordine di compilazione. La prima destinazione denominata generatePetClient verrà eseguita prima della destinazione di compilazione principale, quindi l'origine verrà creata prima dell'esecuzione del compilatore. I parametri di ingresso e uscita sono correlati alla compilazione incrementale. MSBuild può confrontare i timestamp dei file di input con i timestamp dei file di output e determinare se ignorare, compilare o ricompilare parzialmente una destinazione.

    Dopo aver installato il pacchetto NuGet NSwag.MSBuild nel progetto, è possibile usare la variabile $(NSwagExe) nel file .csproj per eseguire lo strumento da riga di comando NSwag in una destinazione MSBuild. In questo modo, gli strumenti possono essere facilmente aggiornati tramite NuGet. In questo caso si usa l'attività Exec MSBuild per eseguire il programma NSwag con i parametri necessari per generare l'API REST del client. Consultare il comando NSwag e i relativi parametri .

    È possibile acquisire l'output da <Exec> aggiungendo ConsoleToMsBuild="true" al tag <Exec> e quindi acquisendo l'output usando il parametro ConsoleOutput in un tag <Output>. ConsoleOutput restituisce l'output come Item. Lo spazio vuoto viene tagliato. ConsoleOutput è abilitato quando ConsoleToMSBuild è vero.

    La seconda destinazione denominata forceReGenerationOnRebuild elimina la classe generata durante la pulizia per forzare la rigenerazione del codice generato durante l'esecuzione della destinazione di ricompilazione. Questa destinazione viene eseguita dopo la destinazione predefinita CoreClean di MSBuild.

  8. Eseguire una ricompilazione della soluzione di Visual Studio e visualizzare il client generato nella cartella PetShopRestClient.

  9. Usare ora il client generato. Passare al client Program.cse copiare il codice seguente:

    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}");
           }
       }
    }
    

    Nota

    Questo codice usa new HttpClient() perché è semplice da dimostrare, ma non è la procedura consigliata per il codice reale. La procedura consigliata consiste nell'usare HttpClientFactory per creare un oggetto HttpClient che risolve i problemi noti di HttpClient richiesta, ad esempio problemi di esaurimento delle risorse o DNS non aggiornati. Consultare Usare IHttpClientFactory per l'implementazione di richieste HTTP affidabili.

Felicitazioni! È ora possibile eseguire il programma per vedere come funziona.

Opzione 2: attività personalizzata derivata da ToolTask

In molti casi, l'uso dell'attività Exec è sufficiente per eseguire uno strumento esterno per eseguire operazioni come la generazione di codice client dell'API REST, ma cosa accade se si vuole consentire la generazione del codice client dell'API REST se e solo se non si usa un percorso di Windows assoluto come input? O se è necessario calcolare in qualche modo dove si trova l'eseguibile? Quando si verifica una situazione in cui è necessario eseguire codice per eseguire operazioni aggiuntive, l'attività dello strumento MSBuild è la soluzione migliore. La classe ToolTask è una classe astratta derivata da MSBuild Task. È possibile definire una sottoclasse concreta, che crea un'attività MSBuild personalizzata. Questo approccio consente di eseguire qualsiasi codice necessario per preparare l'esecuzione dei comandi. Dovresti leggere prima l'esercitazione Creare un'attività personalizzata per la generazione di codice.

Si creerà un'attività personalizzata derivata da MSBuild ToolTask che genererà un client API REST, ma sarà progettata per generare un errore se si tenta di fare riferimento alla specifica OpenAPI usando un indirizzo HTTP. NSwag supporta un indirizzo HTTP come input per la specifica OpenAPI, ma per i fini di questo esempio, supponiamo che ci sia un requisito di progettazione che vieti questo.

Il codice completo si trova in questa cartella PetReaderToolTaskExample; è possibile scaricare e dare un'occhiata. In questa esercitazione verranno illustrati in dettaglio alcuni concetti che è possibile applicare ai propri scenari.

  1. Creare un nuovo progetto di Visual Studio per l'attività personalizzata. Chiamarlo RestApiClientGenerator e usare il modello libreria di classi (C#) con .NET Standard 2.0. Assegnare alla soluzione il nome PetReaderToolTaskExample.

  2. Eliminare Class1.cs, generato automaticamente.

  3. Aggiungere i pacchetti NuGet Microsoft.Build.Utilities.Core:

    • Creare una classe denominata RestApiClientGenerator

    • Ereditare da MSBuild ToolTask e implementare il metodo astratto come illustrato nel codice seguente:

      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. Aggiungere i parametri seguenti:

    • InputOpenApiSpec, dove la specifica è
    • ClientClassName, nome della classe generata
    • ClientNamespaceName, spazio dei nomi in cui viene generata la classe
    • FolderClientClass, percorso della cartella in cui si trova la classe
    • NSwagCommandFullPath, percorso completo della directory in cui si trova 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. Installare strumento da riga di comando NSwag. Ti servirà il percorso completo della directory in cui si trova NSwag.exe.

  6. Implementare i metodi astratti:

       protected override string ToolName => "RestApiClientGenerator";
    
       protected override string GenerateFullPathToTool()
       {
           return $"{NSwagCommandFullPath}\\NSwag.exe";
       }
    
  7. Esistono molti metodi che è possibile sovrascrivere. Per l'implementazione corrente, definire questi due elementi:

    • Definire il parametro del comando:
      protected override string GenerateCommandLineCommands()
      {
          return $"openapi2csclient /input:{InputOpenApiSpec}  /classname:{ClientClassName} /namespace:{ClientNamespaceName} /output:{FolderClientClass}\\{ClientClassName}.cs";
      }
    
    • Convalida dei parametri:
    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;
    }
    

    Nota

    Questa semplice convalida può essere eseguita in altro modo nel file MSBuild, ma è consigliabile eseguirla nel codice C# e incapsulare il comando e la logica.

  8. Costruisci il progetto.

Creare un'app console per usare la nuova attività MSBuild

Il passaggio successivo consiste nel creare un'app che usa l'attività.

  1. Creare un progetto di applicazione console e chiamarlo PetReaderToolTaskConsoleApp. Scegliere .NET 6.0. Contrassegnarlo come progetto di avvio.

  2. Creare un progetto di libreria di classi per generare il codice, denominato PetRestApiClient. Usare .NET Standard 2.1.

  3. Nel progetto PetReaderToolTaskConsoleApp creare una dipendenza del progetto per PetRestApiClient.

  4. Nel progetto PetRestApiClient creare una cartella PetRestApiClient. Questa cartella conterrà il codice generato.

  5. Eliminare Class1.cs, generato automaticamente.

  6. In PetRestApiClientaggiungere i pacchetti NuGet seguenti:

    • Newtonsoft.Json, necessario per compilare il client generato
    • System.ComponentModel.Annotations, necessario per compilare il client generato
  7. Nel progetto PetRestApiClient creare un file di testo denominato petshop-openapi-spec.json (nella cartella del progetto). Per aggiungere la specifica OpenAPI, copiare il contenuto da qui nel file. Ci piace una compilazione riproducibile che dipende solo dall'input, come discusso in precedenza. In questo esempio verrà generato un errore di compilazione se un utente sceglie un URL come input della specifica OpenAPI.

    Importante

    Una ricompilazione generale non funzionerà. Verranno visualizzati errori che indicano che non è possibile copiare o eliminare RestApiClientGenerator.dll'. Questo perché sta tentando di costruire l'attività personalizzata MBuild nello stesso processo di compilazione che lo utilizza. Selezionare PetReaderToolTaskConsoleApp e ricompilare solo quel progetto. L'altra soluzione consiste nell'inserire l'attività personalizzata in una soluzione di Visual Studio completamente indipendente, come hai fatto nell'esempio : esercitazione: Creare un'attività personalizzata nell'esempio.

  8. Copiare il codice seguente in 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. Modificare le istruzioni di MSBuild per chiamare l'attività e generare il codice. Modificare PetRestApiClient.csproj seguendo questa procedura:

    1. Registrare l'uso dell'attività personalizzata MSBuild:

      <UsingTask TaskName="RestApiClientGenerator.RestApiClientGenerator" AssemblyFile="..\RestApiClientGenerator\bin\Debug\netstandard2.0\RestApiClientGenerator.dll" />
      
    2. Aggiungere alcune proprietà necessarie per eseguire l'attività:

       <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>
      

      Importante

      Selezionare il valore NSwagCommandFullPath appropriato in base alla posizione di installazione sul tuo sistema.

    3. Aggiungere un obiettivo MSBuild per generare il client durante il processo di compilazione. Questa destinazione deve essere eseguita prima dell'esecuzione di CoreCompile per generare il codice usato nella compilazione.

      <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 e Output sono correlati alla compilazione incrementale , e l'obiettivo forceReGenerationOnRebuild elimina il file generato dopo CoreClean, forzando la rigenerazione del client durante l'operazione di ricompilazione.

  10. Selezionare PetReaderToolTaskConsoleApp e ricompilare solo quel progetto. Il codice client viene ora generato e il codice viene compilato. È possibile eseguirlo e vedere come funziona. Questo codice genera il codice da un file e questo è consentito.

  11. In questo passaggio verrà illustrata la convalida dei parametri. In PetRestApiClient.csprojmodificare la proprietà $(PetClientInputOpenApiSpec) per usare l'URL:

      <PetClientInputOpenApiSpec>https://petstore.swagger.io/v2/swagger.json</PetClientInputOpenApiSpec>
    
  12. Selezionare PetReaderToolTaskConsoleApp e ricompilare solo quel progetto. Verrà visualizzato l'errore "URL non consentito" in base ai requisiti di progettazione.

Scaricare il codice

Installare lo strumento da riga di comando NSwag. Ti sarà quindi necessario il percorso completo della directory in cui si trova NSwag.exe. Successivamente, modificare PetRestApiClient.csproj e selezionare il valore $(NSwagCommandFullPath) appropriato in base al percorso di installazione nel computer. Ora, selezionare RestApiClientGenerator e compilare solo quel progetto, e infine selezionare e ricompilare PetReaderToolTaskConsoleApp. È possibile eseguire PetReaderToolTaskConsoleApp. per verificare che tutto funzioni come previsto.

Passaggi successivi

Potresti voler pubblicare la tua attività personalizzata come pacchetto NuGet.

In alternativa, informazioni su come testare un'attività personalizzata.