Consumo de un servicio REST con HttpClient

Completado

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.

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

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.

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

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 del HttpRequestMessage usando la función JsonContent.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 un HttpResponseMessage 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
}

Prueba de conocimientos

1.

¿Qué verbo HTTP usa para crear un nuevo recurso en un servicio web REST?

2.

¿A qué método de la clase HttpResponseMessage debería llamar para comprobar que una solicitud HTTP se ha realizado correctamente?