Consumir um serviço REST com HttpClient
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.
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.
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
doHttpRequestMessage
usando a funçãoJsonContent.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 umHttpResponseMessage
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
}