Consumo de un servicio REST con HttpClient
Muchos servicios web modernos implementan la arquitectura REST. Esta estructura permite que un servicio web exponga operaciones y datos a través de una serie de puntos de conexión bien definidos. Las solicitudes que envían las aplicaciones cliente a un servicio web REST para recuperar, modificar, crear o eliminar datos usan un conjunto predefinido de verbos. Un servicio web REST responde a estas solicitudes de forma estándar. Este enfoque hace que sea más fácil construir aplicaciones de cliente.
El modelo REST se basa en el protocolo HTTP. Una aplicación .NET MAUI puede enviar solicitudes a un servicio web REST mediante la clase HttpClient
. En esta unidad obtendrá información sobre HttpClient
y cómo usarlo para interactuar con un servicio web REST.
¿Qué es la clase HttpClient?
HttpClient
es una clase .NET que una aplicación puede usar para enviar solicitudes HTTP y recibir respuestas HTTP de un servicio web REST. Un conjunto de URI identifica los recursos que expone el servicio web. Un URI combina la dirección del servicio web con el nombre de un recurso disponible en esa dirección.
La clase HttpClient
usa una API basada en tareas para el rendimiento y le proporciona acceso a la información de los mensajes de las solicitudes, como encabezados HTTP y códigos de estado, así como a cuerpos de mensajes que contienen los datos reales que se envían y reciben.
La clase HttpClient
está disponible en el espacio de nombres System.Net.Http
. Una aplicación puede crear un objeto HttpClient
mediante el constructor predeterminado:
using System.Net.Http;
...
var client = new HttpClient();
Realizar operaciones CRUD con HttpClient
Un servicio web REST permite a un cliente realizar operaciones con datos mediante un conjunto de verbos HTTP. El trabajo del verbo HTTP es indicar la acción deseada que se va a realizar en un recurso. Hay muchos verbos HTTP, pero los cuatro más habituales son POST
, GET
, PUT
y DELETE
. Un servicio puede implementar estos verbos para permitir que una aplicación cliente administre el ciclo de vida de los objetos mediante las operaciones Crear, Leer, Actualizar y Eliminar (Create, Read, Update y Delete —CRUD), de la siguiente manera:
El verbo
POST
indica que se quiere crear un nuevo recurso.El verbo
GET
indica que se quiere recuperar un recurso.El verbo
PUT
indica que se quiere actualizar un recurso.El verbo
DELETE
indica que se quiere eliminar un recurso.
Creación de un nuevo recurso con HttpClient
Para crear un nuevo recurso mediante HttpClient
, puede usar el método SendAsync
pasándole un objeto HttpRequestMessage
.
El HttpRequestMessage
se usa para modelar la solicitud que se envía al servicio web. Especifique el verbo HTTP, la dirección URL del servicio web y rellene cualquier carga que se envíe a través de la propiedad 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);
Este fragmento de código realiza las siguientes tareas:
- Crea una instancia de
HttpClient
, llamada cliente, que usa para enviar un mensaje. - Crea una instancia de
HttpRequestMessage
, llamada mensaje, que usa para modelar el mensaje. El mensaje tiene el verbo HTTP y la dirección URL. - Establece la propiedad
Content
delHttpRequestMessage
usando la funciónJsonContent.Create
. Esa función serializa automáticamente la variable part en JSON adecuado para enviar al servicio web. - Envía el mensaje con el objeto
HttpClient
. Se devuelve unHttpResponseMessage
que contiene información como el código de estado y la información devuelta por el servicio web.
Lectura de un recurso con HttpClient
Puede leer un recurso de un servicio web con la misma técnica descrita anteriormente, excepto que debería inicializar HttpRequestMessage
con un HttpMethod.Get
. Sin embargo, HttpClient
tiene un par de métodos prácticos que proporcionan accesos directos.
Para leer un recurso mediante HTTPClient
, use el método GetStringAsync
como se muestra en el ejemplo siguiente:
HttpClient client = new HttpClient();
string text = await client.GetStringAsync("https://...");
El método GetStringAsync
toma un URI que hace referencia al recurso y devuelve una respuesta como una cadena. La respuesta de cadena es el recurso que ha solicitado la aplicación. El formato de datos de respuesta es el predeterminado para el servicio solicitado, como JSON o XML. Una aplicación puede indicar al servicio web que necesita que los datos se devuelvan en un formato específico si agrega el encabezadoMediaTypeWithQualityHeaderValue
. Por ejemplo, si la aplicación solicita que los datos se devuelvan en formato JSON, puede usar el siguiente código:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
En este ejemplo el resultado se devuelve como una cadena y solo contiene el cuerpo del mensaje de respuesta. Para obtener toda la respuesta, incluidos los encabezados, el cuerpo y el código de estado, llame al método GetAsync
. Los datos se devuelven como un objeto HttpResponseMessage
.
Actualización de un recurso con HttpClient
Para actualizar un recurso mediante HttpClient
, use un HttpRequestMessage
inicializado con un verbo PUT. El código siguiente es similar al que se necesita para crear un nuevo recurso:
HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Put, url);
message.Content = JsonContent.Create<Part>(part);
HttpResponseMessage response = await client.SendAsync(message);
Nota
La diferencia fundamental entre POST
y PUT
es la idempotencia. Si repite la misma solicitud PUT
varias veces, el mismo recurso se actualizará con los mismos datos y el efecto es el mismo que si la solicitud se hubiera enviado solo una vez. Si emite la misma solicitud POST
varias veces, el resultado será el servicio REST que crea varias copias del recurso.
Eliminación de un recurso con HttpClient
Para eliminar un recurso mediante HttpClient
, llame a SendAsync
con un HttpRequestMessage
inicializado con un verbo DELETE:
HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Delete, url);
HttpResponseMessage response = await client.SendAsync(message);
La respuesta contiene los encabezados, el código de estado y el objeto eliminado.
Administrar las respuestas de una solicitud
Todas las solicitudes HTTP devuelven un mensaje de respuesta. Los datos de la respuesta dependen del verbo que envió la aplicación. Por ejemplo, el cuerpo de respuesta de una solicitud HTTP GET
contiene los datos del recurso solicitado.
El cuerpo de respuesta de una solicitud POST
devuelve una copia del recurso creado, pero el cuerpo de respuesta de una solicitud PUT
debe estar vacío.
Siempre debe comprobar y controlar el código de estado en el mensaje de respuesta. Si este código de estado se encuentra en el intervalo de 200 (200, 201, 202, etc.), se considera que la operación ha tenido éxito, aunque se podría requerir más información más adelante.
Un código de estado en el rango 300 indica que el servicio web podría haber redirigido la solicitud a una dirección diferente, posiblemente como resultado de un recurso que se mueve a una ubicación diferente.
Un código de estado del rango 400 indica un error de aplicación o cliente. Por ejemplo, el código de estado 403 significa que el servicio web requiere la autenticación del usuario, pero la aplicación no lo ha hecho. El código de estado 404 se produce cuando la aplicación intenta acceder a un recurso que no existe.
Los códigos de estado del rango 500 son indicativos de un error del lado servidor, como que el servicio no está disponible o está demasiado ocupado para administrar la solicitud.
El objeto HttpResponseMessage
devuelto por una solicitud enviada a través de un objeto HttpClient
puede abstraer gran parte de la complejidad de controlar los diferentes códigos de estado. Este fragmento de código muestra cómo comprobar que el código de estado de un mensaje de respuesta es un código de correcto, así como controlar los códigos de estado que indican algún tipo de error.
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
}