Delen via


Zelfstudie: Een REST API-client genereren

Een toepassing die een REST API gebruikt, is een veelvoorkomend scenario. Meestal moet u clientcode genereren die uw toepassing kan gebruiken om de REST API aan te roepen. In deze zelfstudie leert u hoe u de REST API-client automatisch genereert tijdens het buildproces met behulp van MSBuild. U gebruikt NSwag, een hulpprogramma waarmee clientcode voor een REST API wordt gegenereerd.

De volledige voorbeeldcode is beschikbaar op REST API-clientgeneratie in de opslagplaats .NET-voorbeelden op GitHub.

In het voorbeeld ziet u een console-app die gebruikmaakt van de openbare Pet Store-API, waarmee een OpenAPI-specificatiewordt gepubliceerd.

In de zelfstudie wordt ervan uitgegaan dat u basiskennis hebt van MSBuild-termen, zoals taken, doelen, eigenschappen of runtimes; zie MSBuild Concepts-artikelvoor de benodigde achtergrond.

Wanneer u een opdrachtregelprogramma wilt uitvoeren als onderdeel van een build, zijn er twee manieren om rekening mee te houden. Een is het gebruik van de MSBuild Exec-taak, waarmee u een opdrachtregelprogramma kunt uitvoeren en de parameters kunt opgeven. De andere methode is het maken van een aangepaste taak die is afgeleid van ToolTask, waardoor u meer controle hebt.

Voorwaarden

U moet inzicht hebben in MSBuild-concepten, zoals taken, doelen en eigenschappen. Zie MSBuild-concepten.

Voor de voorbeelden is MSBuild vereist. Deze is geïnstalleerd met Visual Studio, maar kan ook afzonderlijk worden geïnstalleerd. Zie MSBuild downloaden zonder Visual Studio.

Optie 1: Exec-taak

De Exec-taak roept het opgegeven proces aan met de opgegeven argumenten, wacht tot deze is voltooid en retourneert vervolgens true als het proces is voltooid en false als er een fout optreedt.

NSwag-codegeneratie kan worden gebruikt vanuit MSBuild; zie NSwag.MSBuild.

De volledige code bevindt zich in de map PetReaderExecTaskExample; u kunt downloaden en een kijkje nemen. In deze zelfstudie zult u stapsgewijs doorlopen en leert u gaandeweg de concepten.

  1. Maak een nieuwe consoletoepassing met de naam PetReaderExecTaskExample. Gebruik .NET 6.0 of hoger.

  2. Maak een ander project in dezelfde oplossing: PetShopRestClient (deze oplossing bevat de gegenereerde client als bibliotheek). Gebruik voor dit project .NET Standard 2.1. De gegenereerde client compileert niet op .NET Standard 2.0.

  3. Voeg in het PetReaderExecTaskExample project een projectafhankelijkheid toe aan PetShopRestClient project.

  4. Neem in het PetShopRestClient project de volgende NuGet-pakketten op:

    • Nswag.MSBuild, waarmee toegang tot de codegenerator vanuit MSBuild wordt toegestaan
    • Newtonsoft.Json, nodig om de gegenereerde client te compileren
    • System.ComponentModel.Annotations, nodig om de gegenereerde client te compileren
  5. Voeg in het PetShopRestClient project een map (met de naam PetShopRestClient) toe voor het genereren van code en verwijder de Class1.cs die automatisch is gegenereerd.

  6. Maak een tekstbestand met de naam petshop-openapi-spec.json in de hoofdmap van het project. Kopieer de OpenAPI-specificatie uit hier en sla deze op in het bestand. U kunt het beste een momentopname van de specificatie kopiëren in plaats van deze online te lezen tijdens de build. U wilt altijd een consistent reproduceerbare build die alleen afhankelijk is van de invoer. Het rechtstreeks gebruiken van de API kan een build transformeren die vandaag werkt naar een build die morgen uit dezelfde bron mislukt. Met de momentopname die is opgeslagen op petshop-openapi-spec.json kunnen we nog steeds een versie hebben die wordt gebouwd, zelfs als de specificatie verandert.

  7. Wijzig vervolgens PetShopRestClient.csproj en voeg een MSBuild-doelen toe om de client te genereren tijdens het buildproces.

    Voeg eerst enkele eigenschappen toe die nuttig zijn voor het genereren van clients:

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

    Voeg de volgende doelen toe:

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

    U ziet dat dit doel gebruikmaakt van de kenmerken BeforeTarget en AfterTarget als manier om de buildvolgorde te definiëren. Het eerste doel met de naam generatePetClient wordt uitgevoerd vóór het kerncompilatiedoel, dus de bron wordt gemaakt voordat de compiler wordt uitgevoerd. De invoer- en uitvoerparameters zijn gerelateerd aan incrementele build. MSBuild kan de tijdstempels van de invoerbestanden vergelijken met de tijdstempels van de uitvoerbestanden en bepalen of een doel moet worden overgeslagen, gebouwd of gedeeltelijk opnieuw moet worden opgebouwd.

    Nadat u het NSwag.MSBuild NuGet-pakket in uw project hebt geïnstalleerd, kunt u de variabele $(NSwagExe) in uw .csproj-bestand gebruiken om het opdrachtregelprogramma NSwag uit te voeren in een MSBuild-doel. Op deze manier kunnen de hulpprogramma's eenvoudig worden bijgewerkt via NuGet. Hier gebruikt u de Exec MSBuild-taak om het NSwag-programma uit te voeren met de vereiste parameters om de client REST API te genereren. Zie NSwag-opdracht en parameters.

    U kunt uitvoer van <Exec> vastleggen door ConsoleToMsBuild="true" aan uw <Exec> tag toe te voegen en vervolgens de uitvoer te verzamelen met behulp van de ConsoleOutput parameter in een <Output> tag. ConsoleOutput retourneert de uitvoer als een Item. Witruimte is verwijderd. ConsoleOutput is ingeschakeld wanneer ConsoleToMSBuild waar is.

    Het tweede doel met de naam forceReGenerationOnRebuild verwijdert de gegenereerde klasse tijdens het opschonen om de regeneratie van de gegenereerde code af te dwingen tijdens het opnieuw opbouwen van de doeluitvoering. Dit doel wordt uitgevoerd nadat het vooraf gedefinieerde CoreClean MSBuild-doel is voltooid.

  8. Voer een Visual Studio Solution-herbouw uit en bekijk de client die is gegenereerd in de map PetShopRestClient.

  9. Gebruik nu de gegenereerde client. Ga naar de client Program.csen kopieer de volgende code:

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

    Notitie

    Deze code maakt gebruik van new HttpClient() omdat het eenvoudig te demonstreren is, maar het is niet de best practice voor echte code. De best practice is om HttpClientFactory te gebruiken om een HttpClient-object te maken waarmee de bekende problemen van HttpClient aanvraag, zoals resourceuitputting of verlopen DNS-problemen, worden opgelost. Zie IHttpClientFactory gebruiken om tolerante HTTP-aanvragen te implementeren.

Gefeliciteerd! Nu kunt u het programma uitvoeren om te zien hoe het werkt.

Optie 2: Aangepaste taak afgeleid van ToolTask

In veel gevallen is het gebruik van de Exec-taak goed genoeg om een extern hulpprogramma uit te voeren om iets te doen zoals het genereren van REST API-clientcode, maar wat als u het genereren van REST API-clientcode wilt toestaan als en alleen als u geen absoluut Windows-pad als invoer gebruikt? Of wat moet u doen als u op een bepaalde manier moet berekenen waar het uitvoerbare bestand zich bevindt? Wanneer er een situatie is waarin u code moet uitvoeren om extra werk uit te voeren, is de MSBuild Tool Task de beste oplossing. De ToolTask-klasse is een abstracte klasse die is afgeleid van MSBuild Task. U kunt een concrete subklasse definiëren, waarmee een aangepaste MSBuild-taak wordt gemaakt. Met deze methode kunt u alle code uitvoeren die nodig is om de uitvoering van opdrachten voor te bereiden. Lees de zelfstudie Maak eerst een aangepaste taak voor het genereren van code.

U maakt een aangepaste taak die is afgeleid van MSBuild ToolTask- die een REST API-client genereert, maar deze wordt ontworpen om een fout te verzenden als u probeert te verwijzen naar de OpenAPI-specificatie met behulp van een HTTP-adres. NSwag ondersteunt een HTTP-adres als openAPI-specificatieinvoer, maar voor het doel van dit voorbeeld is er een ontwerpvereiste om dit niet toe te staan.

De volledige code bevindt zich in deze PetReaderToolTaskExample map; u kunt downloaden en een kijkje nemen. In deze zelfstudie doorloopt u stapsgewijs enkele concepten die u op uw eigen scenario's kunt toepassen.

  1. Maak een nieuw Visual Studio-project voor de aangepaste taak. Noem deze RestApiClientGenerator en gebruik de sjabloon Class Library (C#) met .NET Standard 2.0. Noem de oplossing PetReaderToolTaskExample.

  2. Verwijder Class1.cs, dat automatisch is gegenereerd.

  3. Voeg de Microsoft.Build.Utilities.Core NuGet-pakketten toe:

    • Maak een klasse met de naam RestApiClientGenerator

    • Overnemen van MSBuild ToolTask en de abstracte methode implementeren, zoals wordt weergegeven in de volgende code:

      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. Voeg de volgende parameters toe:

    • InputOpenApiSpec, waar de specificatie zich bevindt
    • ClientClassName, naam van de gegenereerde klasse
    • ClientNamespaceName, naamruimte waar de klasse wordt gegenereerd
    • FolderClientClass, pad naar de map waar de klasse zich bevindt
    • NSwagCommandFullPath, volledig pad naar de map waar NSwag.exe zich bevindt
         [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. Installeer NSwag-opdrachtregelprogramma. U hebt het volledige pad naar de map nodig waar NSwag.exe zich bevindt.

  6. Implementeer de abstracte methoden:

       protected override string ToolName => "RestApiClientGenerator";
    
       protected override string GenerateFullPathToTool()
       {
           return $"{NSwagCommandFullPath}\\NSwag.exe";
       }
    
  7. Er zijn veel methoden die u kunt overschrijven. Definieer deze twee voor de huidige implementatie:

    • Definieer de opdrachtparameter:
      protected override string GenerateCommandLineCommands()
      {
          return $"openapi2csclient /input:{InputOpenApiSpec}  /classname:{ClientClassName} /namespace:{ClientNamespaceName} /output:{FolderClientClass}\\{ClientClassName}.cs";
      }
    
    • Parametervalidatie:
    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;
    }
    

    Notitie

    Deze eenvoudige validatie kan op een andere manier worden uitgevoerd in het MSBuild-bestand, maar het wordt aanbevolen dit te doen in C#-code en de opdracht en de logica inkapselen.

  8. Bouw het project.

Een console-app maken voor het gebruik van de nieuwe MSBuild-taak

De volgende stap is het maken van een app die gebruikmaakt van de taak.

  1. Maak een Console-app project en noem het PetReaderToolTaskConsoleApp. Kies .NET 6.0. Markeer het als opstartproject.

  2. Maak een klassebibliotheek project om de code te genereren, genaamd PetRestApiClient. .NET Standard 2.1 gebruiken.

  3. Maak in het PetReaderToolTaskConsoleApp project een projectafhankelijkheid voor PetRestApiClient.

  4. Maak in het PetRestApiClient project een map PetRestApiClient. Deze map bevat de gegenereerde code.

  5. Verwijder Class1.cs, dat automatisch is gegenereerd.

  6. Voeg in PetRestApiClientde volgende NuGet-pakketten toe:

    • Newtonsoft.Json, nodig om de gegenereerde client te compileren
    • System.ComponentModel.Annotations, nodig om de gegenereerde client te compileren
  7. Maak in het PetRestApiClient project een tekstbestand met de naam petshop-openapi-spec.json (in de projectmap). Als u de OpenAPI-specificatie wilt toevoegen, kopieert u de inhoud van hier naar het bestand. We vinden een reproduceerbare build leuk die alleen afhankelijk is van de invoer, zoals eerder besproken. In dit voorbeeld genereert u een buildfout als een gebruiker een URL kiest als de invoer van de OpenAPI-specificatie.

    Belangrijk

    Een algemene herbouw werkt niet. Je ziet fouten die aangeven dat RestApiClientGenerator.dllniet kan worden gekopieerd of verwijderd. Dit komt omdat het probeert de aangepaste MBuild-taak te bouwen in hetzelfde buildproces dat deze gebruikt. Selecteer PetReaderToolTaskConsoleApp en bouw alleen dat project opnieuw. Een andere oplossing is om de aangepaste taak in een volledig onafhankelijke Visual Studio-oplossing te plaatsen, zoals je deed in het zelfstudie voorbeeld: 'Een aangepaste taak maken'.

  8. Kopieer de volgende code naar 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. Wijzig de MSBuild-instructies om de taak aan te roepen en de code te genereren. Bewerk PetRestApiClient.csproj door de volgende stappen uit te voeren:

    1. Registreer het gebruik van de aangepaste MSBuild-taak:

      <UsingTask TaskName="RestApiClientGenerator.RestApiClientGenerator" AssemblyFile="..\RestApiClientGenerator\bin\Debug\netstandard2.0\RestApiClientGenerator.dll" />
      
    2. Voeg enkele eigenschappen toe die nodig zijn om de taak uit te voeren:

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

      Belangrijk

      Selecteer de juiste NSwagCommandFullPath waarde op basis van de installatielocatie op uw systeem.

    3. Voeg een MSBuild-target toe om de client te genereren tijdens de buildfase. Dit doel moet worden uitgevoerd voordat CoreCompile wordt uitgevoerd om de code te genereren die in de compilatie wordt gebruikt.

      <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 en Output zijn gerelateerd aan incrementele build-en het forceReGenerationOnRebuild doel verwijdert het gegenereerde bestand na CoreClean, waardoor de client opnieuw moet worden gegenereerd tijdens de herbouwbewerking.

  10. Selecteer PetReaderToolTaskConsoleApp en bouw alleen dat project opnieuw. Nu wordt de clientcode gegenereerd en wordt de code gecompileerd. U kunt deze uitvoeren en zien hoe het werkt. Met deze code wordt de code gegenereerd op basis van een bestand en dat is toegestaan.

  11. In deze stap demonstreert u de parametervalidatie. Wijzig in PetRestApiClient.csprojde eigenschap $(PetClientInputOpenApiSpec) om de URL te gebruiken:

      <PetClientInputOpenApiSpec>https://petstore.swagger.io/v2/swagger.json</PetClientInputOpenApiSpec>
    
  12. Selecteer PetReaderToolTaskConsoleApp en bouw alleen dat project opnieuw. U krijgt de foutmelding 'URL is niet toegestaan' in overeenstemming met de ontwerpvereiste.

De code downloaden

Installeer de NSwag-opdrachtregeltool . Vervolgens hebt u het volledige pad naar de map nodig waar NSwag.exe zich bevindt. Bewerk daarna PetRestApiClient.csproj en selecteer de juiste $(NSwagCommandFullPath) waarde op basis van het installatiepad op uw computer. Selecteer nu RestApiClientGenerator en bouw alleen dat project, en selecteer en herbouw tot slot PetReaderToolTaskConsoleApp. U kunt PetReaderToolTaskConsoleAppuitvoeren. om te controleren of alles werkt zoals verwacht.

Volgende stappen

Mogelijk wilt u uw aangepaste taak publiceren als een NuGet-pakket.

Of leer hoe u een aangepaste taak test.