Consumir um serviço REST com HttpClient

Concluído

Muitos serviços Web modernos implementam a arquitetura REST. Essa estrutura permite que um serviço Web exponha operações e dados por meio de uma série de pontos de extremidade bem definidos. As solicitações que os aplicativos cliente enviam a um serviço Web REST para recuperar, modificar, criar ou excluir dados usam um conjunto predefinido de verbos. Um serviço Web REST responde a essas solicitações de maneira padrão. Essa abordagem facilita a construção de aplicativos cliente.

O modelo REST é baseado no protocolo HTTP. Um aplicativo .NET MAUI pode enviar solicitações a um serviço Web REST usando a classe HttpClient. Nesta unidade, você aprenderá sobre HttpClient e como usá-la para interagir com um serviço Web REST.

O que é a classe HttpClient?

HttpClient é uma classe .NET que um aplicativo pode usar para enviar solicitações HTTP e receber respostas HTTP de um serviço Web REST. Um conjunto de URIs identifica os recursos expostos pelo serviço Web. Um URI combina o endereço do serviço Web com o nome de um recurso disponível nesse endereço.

A classe HttpClient usa uma API baseada em tarefas para desempenho e fornece acesso a informações em mensagens de solicitação, como cabeçalhos HTTP e códigos de status, bem como corpos de mensagens que contêm os dados reais que estão sendo enviados e recebidos.

Diagram showing how a client app uses an HttpClient object to send and receive HTTP messages and responses

A classe HttpClient está disponível no namespace System.Net.Http. Um aplicativo pode criar um objeto HttpClient usando o construtor padrão:

using System.Net.Http;
...

var client = new HttpClient();

Executar operações CRUD com um objeto HttpClient

Um serviço Web REST permite que um cliente execute operações em dados por meio de um conjunto de verbos HTTP. O trabalho do verbo HTTP é indicar a ação desejada a ser executada em um recurso. Há muitos verbos HTTP, mas os quatro mais comuns são POST, GET, PUT e DELETE. Um serviço pode implementar esses verbos para permitir que um aplicativo cliente gerencie o ciclo de vida dos objetos executando operações CRUD (Criar, Ler, Atualizar e Excluir), da seguinte maneira:

  • O verbo POST indica que você quer criar um recurso.

  • O verbo GET indica que você quer recuperar um recurso.

  • O verbo PUT indica que você quer atualizar um recurso.

  • O verbo DELETE indica que você quer excluir um recurso.

Diagram showing the basic CRUD operations that a REST service can implement, including get, post, put and delete.

Criar um recurso com HttpClient

Para criar um recurso usando HttpClient, você pode usar o método SendAsync passando um objeto HttpRequestMessage a ele.

O HttpRequestMessage tem a finalidade de modelar a solicitação enviada ao serviço Web. Especifique o verbo HTTP, a URL do serviço Web e preencha qualquer conteúdo a ser enviado por meio da propriedade HttpRequestMessage.Content.

HttpClient client = new HttpClient();

HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url);
message.Content = JsonContent.Create<Part>(part);

HttpResponseMessage response = await client.SendAsync(message);

Esse fragmento de código executa as seguintes tarefas:

  • Ele cria uma instância de HttpClient chamada client, que usa para enviar uma mensagem.
  • Ele cria uma instância de HttpRequestMessage chamada message, que usa para modelar a mensagem. A mensagem tem o verbo HTTP e a URL.
  • Ele define a propriedade Content do HttpRequestMessage usando a função JsonContent.Create. Essa função serializa automaticamente a variável de parte em JSON adequado para envio ao serviço Web.
  • Ele envia a mensagem usando o objeto HttpClient. É retornado um HttpResponseMessage que contém informações como o código de status e as informações retornadas pelo serviço Web.

Ler um recurso com HttpClient

Você pode ler um recurso de um serviço Web usando a mesma técnica descrita anteriormente, exceto inicializando o HttpRequestMessage com um HttpMethod.Get. No entanto, HttpClient tem alguns métodos de conveniência que fornecem atalhos.

Para ler um recurso usando HTTPClient, use o método GetStringAsync, conforme mostrado no próximo exemplo:

HttpClient client = new HttpClient();

string text = await client.GetStringAsync("https://...");

O método GetStringAsync usa um URI que faz referência ao recurso e retorna uma resposta como uma cadeia de caracteres. A resposta da cadeia de caracteres é o recurso solicitado pelo aplicativo. O formato de dados de resposta é o padrão para o serviço solicitado, como JSON ou XML. Um aplicativo pode informar ao serviço Web que ele exige que os dados sejam retornados em um formato específico adicionando o cabeçalho MediaTypeWithQualityHeaderValue. Por exemplo, se o aplicativo solicitar que os dados sejam enviados no formato JSON, ele poderá usar o seguinte código:

HttpClient client = new HttpClient();

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

Neste exemplo, o resultado é retornado como uma cadeia de caracteres e contém apenas o corpo da mensagem de resposta. Para obter toda a resposta, incluindo os cabeçalhos, o corpo e o código de status, chame o método GetAsync. Os dados são retornados como um objeto HttpResponseMessage.

Atualizar um recurso com HttpClient

Para atualizar um recurso usando HttpClient, use um HttpRequestMessage inicializado com um verbo PUT. O seguinte código é semelhante ao necessário para criar um recurso:

HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Put, url);

message.Content = JsonContent.Create<Part>(part);

HttpResponseMessage response = await client.SendAsync(message);

Observação

A diferença fundamental entre POST e PUT é a idempotência. Se você repetir a mesma solicitação PUT várias vezes, o mesmo recurso será atualizado com os mesmos dados e o efeito será o mesmo que seria obtido se a solicitação tivesse sido enviada apenas uma vez. Se você emitir a mesma solicitação POST várias vezes, o resultado será o serviço REST criar várias cópias do recurso.

Excluir um recurso com HttpClient

Para excluir um recurso usando HttpClient, chame SendAsync com um HttpRequestMessage inicializado com um verbo DELETE:

HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Delete, url);

HttpResponseMessage response = await client.SendAsync(message);

A resposta conterá os cabeçalhos, o código de status e o objeto excluído.

Manipular respostas de uma solicitação

Todas as solicitações HTTP retornam uma mensagem de resposta. Os dados na resposta dependem de qual verbo o aplicativo enviou. Por exemplo, o corpo da resposta de uma solicitação GET HTTP contém os dados do recurso solicitado.

O corpo da resposta de uma solicitação POST retorna uma cópia do recurso criado, mas o corpo da resposta de uma solicitação PUT deve estar vazio.

Sempre verifique e manipule o código de status na mensagem de resposta. Se esse código de status estiver no intervalo de 200 (200, 201, 202 e assim por diante), a operação será considerada bem-sucedida, embora mais informações possam ser necessárias posteriormente.

Um código de status no intervalo 300 indica que a solicitação pode ter sido redirecionada pelo serviço Web para um endereço diferente, possivelmente como resultado de um recurso migrando para um local diferente.

Um código de status no intervalo 400 indica um erro do cliente ou do aplicativo. Por exemplo, o código de status 403 significa que o serviço Web exige que o usuário seja autenticado, mas o aplicativo não fez isso. O código de status 404 ocorre quando o aplicativo tenta acessar um recurso que não existe.

Códigos de status no intervalo 500 indicam um erro no lado do servidor, como o serviço estar indisponível ou muito ocupado para lidar com a solicitação.

O objeto HttpResponseMessage retornado por uma solicitação enviada por meio de um objeto HttpClient pode abstrair grande parte da complexidade de lidar com os diferentes códigos de status. Esse fragmento de código mostra como verificar se o código de status em uma mensagem de resposta indica êxito e como lidar com códigos de status que indicam alguma falha.

static readonly HttpClient client = new HttpClient();

...
// Call asynchronous network methods in a try/catch block to handle exceptions.
try
{
    //... Initiate the HttpRequest

    HttpResponseMessage response = await client.SendAsync(msg);
    response.EnsureSuccessStatusCode(); // Check that the status code is in the 200 range. Throw an HttpRequestException if not
    
    string responseBody = await response.Content.ReadAsStringAsync();
    
    ... // Handle the response
}
catch(HttpRequestException e)
{
    ... // Handle any status codes that indicate an error. 
        // The status code is available in the field e.StatusCode
}

Verificação de conhecimento

1.

Qual verbo HTTP você usa para criar um recurso em um serviço Web REST?

2.

Qual método da classe HttpResponseMessage você deve chamar para verificar se uma solicitação HTTP foi bem-sucedida?"