Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Um aplicativo que consome uma API REST é um cenário muito comum. Normalmente, você precisa gerar o código do cliente que seu aplicativo pode usar para chamar a API REST. Neste tutorial, você aprenderá a gerar o cliente da API REST automaticamente durante o processo de build usando o MSBuild. Você usará NSwag, uma ferramenta que gera o código do cliente para uma API REST.
O código de exemplo completo está disponível na geração de cliente da API REST, no repositório de exemplos do .NET no GitHub.
O exemplo mostra um aplicativo de console que consome a API pública Pet Store, que publica uma especificação OpenAPI.
O tutorial pressupõe conhecimento básico de termos do MSBuild, como tarefas, destinos, propriedades ou runtimes; para obter o contexto necessário, consulte o artigo sobre conceitos do MSBuild .
Quando você deseja executar uma ferramenta de linha de comando como parte de um build, há duas abordagens a serem consideradas. Uma delas é usar a tarefa MSBuild Exec, que permite executar uma ferramenta de linha de comando e especificar seus parâmetros. O outro método é criar uma tarefa personalizada derivada de ToolTask, o que oferece maior controle.
Pré-requisitos
Você deve ter uma compreensão dos conceitos do MSBuild, como tarefas, destinos e propriedades. Confira Conceitos do MSBuild.
Os exemplos exigem o MSBuild, que é instalado com o Visual Studio, mas também pode ser instalado separadamente. Confira Baixar o MSBuild sem o Visual Studio.
Opção 1: tarefa Exec
A tarefa exec simplesmente invoca o processo especificado com os argumentos especificados, aguarda a conclusão e retorna true
se o processo for concluído com êxito e false
se ocorrer um erro.
A geração de código NSwag pode ser usada do MSBuild; consulte NSwag.MSBuild .
O código completo está na pasta PetReaderExecTaskExample; você pode baixar e dar uma olhada. Neste tutorial, você passará passo a passo e aprenderá os conceitos a caminho.
Crie um novo aplicativo de console chamado
PetReaderExecTaskExample
. Use o .NET 6.0 ou posterior.Crie outro projeto na mesma solução:
PetShopRestClient
(essa solução conterá o cliente gerado como uma biblioteca). Para este projeto, use o .NET Standard 2.1. O cliente gerado não é compilado no .NET Standard 2.0.No projeto
PetReaderExecTaskExample
, adicione uma dependência de projeto ao projetoPetShopRestClient
.No projeto
PetShopRestClient
, inclua os seguintes pacotes NuGet:- Nswag.MSBuild, que permite o acesso ao gerador de código do MSBuild
- Newtonsoft.Json, necessário para compilar o cliente gerado
- System.ComponentModel.Annotations, necessário para compilar o cliente gerado
No projeto
PetShopRestClient
, adicione uma pasta (denominadaPetShopRestClient
) para a geração de código e exclua o Class1.cs gerado automaticamente.Crie um arquivo de texto chamado petshop-openapi-spec.json na raiz do projeto. Copie a especificação OpenAPI de aqui e salve-a no arquivo. É melhor copiar uma captura da especificação em vez de lê-la online durante a construção. Você sempre deseja um build reproduzível consistentemente que dependa apenas da entrada. Consumir a API diretamente pode transformar um build que funciona hoje em um build que falha amanhã da mesma origem. O instantâneo salvo em petshop-openapi-spec.json nos permitirá ainda ter uma versão que seja compilada mesmo se a especificação for alterada.
Em seguida, modifique PetShopRestClient.csproj e adicione destinos do MSBuild para gerar o cliente durante o processo de build.
Primeiro, adicione algumas propriedades úteis para a geração do cliente:
<PropertyGroup> <PetOpenApiSpecLocation>petshop-openapi-spec.json</PetOpenApiSpecLocation> <PetClientClassName>PetShopRestClient</PetClientClassName> <PetClientNamespace>PetShopRestClient</PetClientNamespace> <PetClientOutputDirectory>PetShopRestClient</PetClientOutputDirectory> </PropertyGroup>
Adicione os seguintes destinos:
<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>
Observe que esse destino usa os atributos BeforeTarget e AfterTarget como forma de definir a ordem de build. O primeiro destino chamado
generatePetClient
será executado antes do destino de compilação principal, portanto, a origem será criada antes da execução do compilador. O parâmetro de entrada e saída está relacionado ao Build Incremental. O MSBuild pode comparar os carimbos de data/hora dos arquivos de entrada com os carimbos de data/hora dos arquivos de saída e determinar se deve ignorar, compilar ou recompilar parcialmente um destino.Depois de instalar o pacote NuGet
NSwag.MSBuild
em seu projeto, você pode usar a variável$(NSwagExe)
em seu arquivo.csproj
para executar a ferramenta de linha de comando NSwag em um destino MSBuild. Dessa forma, as ferramentas podem ser facilmente atualizadas por meio do NuGet. Aqui, você está usando a tarefaExec
MSBuild para executar o programa NSwag com os parâmetros necessários para gerar a API Rest do cliente. Confira Comando NSwag e parâmetros.Você pode capturar a saída de
<Exec>
adicionandoConsoleToMsBuild="true"
à tag<Exec>
e capturando a saída usando o parâmetroConsoleOutput
em uma tag de<Output>
.ConsoleOutput
devolve o resultado comoItem
. O espaço em branco é cortado.ConsoleOutput
é habilitado quandoConsoleToMSBuild
é verdadeiro.O segundo destino chamado
forceReGenerationOnRebuild
exclui a classe gerada durante a limpeza para forçar a regeneração do código gerado durante a execução do destino de recompilação. Esse destino é executado após o destino predefinidoCoreClean
do MSBuild.Execute uma recompilação da Solução do Visual Studio e veja o cliente gerado na pasta
PetShopRestClient
.Agora, use o cliente gerado. Vá para o Program.csdo cliente e copie o seguinte código:
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
Esse código usa
new HttpClient()
porque é simples de demonstrar, mas não é a melhor prática para o código do mundo real. A melhor prática é usarHttpClientFactory
para criar um objetoHttpClient
que resolva os problemas conhecidos deHttpClient
solicitação, como Esgotamento de Recursos ou problemas de DNS obsoletos. Confira Usar IHttpClientFactory para implementar solicitações HTTP resilientes.
Parabéns! Agora, você pode executar o programa para ver como ele funciona.
Opção 2: tarefa personalizada derivada de ToolTask
Em muitos casos, usar a tarefa Exec
é bom o suficiente para executar uma ferramenta externa para fazer algo como a geração de código do cliente da API REST, mas e se você quiser permitir a geração de código do cliente da API REST se e somente se você não usar um caminho absoluto do Windows como entrada? Ou e se você precisar calcular de alguma forma onde o executável está? Quando há qualquer situação em que você precisa executar algum código para executar um trabalho adicional, a Tarefa da Ferramenta MSBuild é a melhor solução. A classe ToolTask
é uma classe abstrata derivada do MSBuild Task
. Você pode definir uma subclasse concreta, que cria uma tarefa personalizada do MSBuild. Essa abordagem permite executar qualquer código necessário para se preparar para a execução do comando. Você deve ler o tutorial Criar uma tarefa personalizada para a geração de código primeiro.
Você criará uma tarefa personalizada derivada de do MSBuild ToolTask que gerará um cliente da API REST, mas ela será projetada para emitir um erro se você tentar referenciar a especificação OpenAPI usando um endereço http. O NSwag dá suporte a um endereço http como entrada de especificação OpenAPI, mas para fins deste exemplo, vamos supor que haja um requisito de design para não permitir isso.
O código completo está nesta pasta PetReaderToolTaskExample
; você pode baixar e dar uma olhada. Neste tutorial, você passará passo a passo e aprenderá alguns conceitos que podem ser aplicados aos seus próprios cenários.
Crie um novo Projeto do Visual Studio para a tarefa personalizada. Chame-o
RestApiClientGenerator
e use o modelo de da Biblioteca de Classes (C#) com o .NET Standard 2.0. Nomeie a soluçãoPetReaderToolTaskExample
.Excluir Class1.cs, que foi gerado automaticamente.
Adicione os pacotes NuGet
Microsoft.Build.Utilities.Core
:Criar uma classe chamada
RestApiClientGenerator
Herda do MSBuild
ToolTask
e implemente o método abstrato, conforme mostrado no seguinte código: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(); } } }
Adicione os seguintes parâmetros:
- InputOpenApiSpec, onde a especificação é
- ClientClassName, nome da classe gerada
- ClientNamespaceName, namespace em que a classe é gerada
- FolderClientClass, caminho para a pasta em que a classe estará localizada
- NSwagCommandFullPath, caminho completo para o diretório onde NSwag.exe está localizado
[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; }
Instale a ferramenta de linha de comando NSwag. Você precisará do caminho completo para o diretório onde NSwag.exe está localizado.
Implemente os métodos abstratos:
protected override string ToolName => "RestApiClientGenerator"; protected override string GenerateFullPathToTool() { return $"{NSwagCommandFullPath}\\NSwag.exe"; }
Há muitos métodos que você pode substituir. Para a implementação atual, defina estes dois:
- Defina o parâmetro de comando:
protected override string GenerateCommandLineCommands() { return $"openapi2csclient /input:{InputOpenApiSpec} /classname:{ClientClassName} /namespace:{ClientNamespaceName} /output:{FolderClientClass}\\{ClientClassName}.cs"; }
- Validação de parâmetro:
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
Essa validação simples pode ser feita de outra forma no arquivo MSBuild, mas é recomendável fazer isso no código C# e encapsular o comando e a lógica.
Compile o projeto.
Criar um aplicativo de console para usar a nova tarefa do MSBuild
A próxima etapa é criar um aplicativo que use a tarefa.
Crie um projeto de Aplicativo de Console e nomeie-o
PetReaderToolTaskConsoleApp
. Escolha .NET 6.0. Marque-o como projeto inicial.Crie um projeto da Biblioteca de Classes para gerar o código, chamado
PetRestApiClient
. Utilize o .NET Standard 2.1.No projeto
PetReaderToolTaskConsoleApp
, crie uma dependência de projeto paraPetRestApiClient
.No projeto
PetRestApiClient
, crie uma pastaPetRestApiClient
. Essa pasta conterá o código gerado.Excluir Class1.cs, que foi gerado automaticamente.
No
PetRestApiClient
, adicione os seguintes pacotes NuGet:- Newtonsoft.Json, necessário para compilar o cliente gerado
- System.ComponentModel.Annotations, necessário para compilar o cliente gerado
No projeto
PetRestApiClient
, crie um arquivo de texto chamado petshop-openapi-spec.json (na pasta do projeto). Para adicionar a especificação OpenAPI, copie o conteúdo de aqui no arquivo. Gostamos de um build reproduzível que depende apenas da entrada, conforme discutido anteriormente. Neste exemplo, você gerará um erro de build se um usuário escolher uma URL como a entrada de especificação OpenAPI.Importante
Uma reconstrução geral não funcionará. Você verá erros que indicam que não é possível copiar ou excluir
RestApiClientGenerator
.dll'. Isso ocorre porque ele está tentando criar a tarefa personalizada do MBuild no mesmo processo de build que a usa. SelecionePetReaderToolTaskConsoleApp
e recompile somente esse projeto. A outra solução é colocar a tarefa personalizada em uma solução completamente independente do Visual Studio, como você fez em Tutorial: Criar uma tarefa personalizada exemplo.Copie o seguinte código para 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}"); } } }
Altere as instruções do MSBuild para chamar a tarefa e gerar o código. Edite PetRestApiClient.csproj seguindo estas etapas:
Registre o uso da tarefa personalizada do MSBuild:
<UsingTask TaskName="RestApiClientGenerator.RestApiClientGenerator" AssemblyFile="..\RestApiClientGenerator\bin\Debug\netstandard2.0\RestApiClientGenerator.dll" />
Adicione algumas propriedades necessárias para executar a tarefa:
<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
Selecione o valor de
NSwagCommandFullPath
adequado com base no local de instalação em seu sistema.Adicione um destino do MSBuild para gerar o cliente durante o processo de compilação. Esse destino deve ser executado antes que
CoreCompile
seja executado para gerar o código usado na compilação.<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
eOutput
estão relacionados ao Build Incremental, e o destinoforceReGenerationOnRebuild
exclui o arquivo gerado apósCoreClean
, o que força o cliente a ser regenerado durante a operação de rebuild.Selecione
PetReaderToolTaskConsoleApp
e recompile somente esse projeto. Agora, o código do cliente é gerado e o código é compilado. Você pode executá-lo e ver como ele funciona. Esse código gera o código de um arquivo e isso é permitido.Nesta etapa, você demonstrará a validação do parâmetro. Em PetRestApiClient.csproj, altere a propriedade
$(PetClientInputOpenApiSpec)
para usar a URL:<PetClientInputOpenApiSpec>https://petstore.swagger.io/v2/swagger.json</PetClientInputOpenApiSpec>
Selecione
PetReaderToolTaskConsoleApp
e recompile somente esse projeto. Você receberá o erro" "A URL não é permitida" de acordo com o requisito de design.
Baixar o código
Instale a ferramenta de linha de comando NSwag. Em seguida, você precisará do caminho completo para o diretório onde NSwag.exe está localizado. Depois disso, edite PetRestApiClient.csproj e selecione o valor de $(NSwagCommandFullPath)
adequado com base no caminho de instalação em seu computador. Agora, selecione RestApiClientGenerator
e crie apenas esse projeto e, por fim, selecione e recompile PetReaderToolTaskConsoleApp
. Você pode executar PetReaderToolTaskConsoleApp
. para verificar se tudo funciona conforme o esperado.
Próximas etapas
Talvez você queira publicar sua tarefa personalizada como um pacote NuGet.
Tutorial : criar uma tarefa personalizada
Ou saiba como testar uma tarefa personalizada.