Compartir a través de


Consumo de un servicio web basado en REST

Browse sample. Examinar la muestra.

Transferencia de estado representacional (REST) es un estilo arquitectónico para compilar servicios web. Las solicitudes REST se suelen realizar a través de HTTP con los mismos verbos HTTP que los exploradores web usan para recuperar páginas web y enviar datos a los servidores. Los verbos son:

  • GET: esta operación se usa para recuperar datos del servicio web.
  • POST: esta operación se usa para crear un nuevo elemento de datos en el servicio web.
  • PUT: esta operación se usa para actualizar un elemento de datos en el servicio web.
  • PATCH: esta operación se usa para actualizar un elemento de datos en el servicio web describiendo un conjunto de instrucciones sobre cómo se debe modificar el elemento.
  • DELETE: esta operación se usa para eliminar un elemento de datos en el servicio web.

Las API de servicio web que se ajustan a REST se definen mediante:

  • Identificador URI base.
  • Métodos HTTP, como GET, POST, PUT, PATCH o DELETE.
  • Un tipo de medio para los datos, como notación de objetos JavaScript (JSON).

Normalmente, los servicios web basados en REST usan mensajes JSON para devolver datos al cliente. JSON es un formato de intercambio de datos basado en texto que genera cargas compactas, lo que reduce los requisitos de ancho de banda al enviar datos. La simplicidad de REST ha contribuido a convertirlo en el principal método de acceso a servicios web en aplicaciones móviles.

Nota:

Acceder a un servicio web requiere a menudo una programación asíncrona. Para obtener más información sobre la programación asincrónica consulta Programación asincrónica con async y await.

Operaciones de servicio web

El servicio REST de ejemplo está escrito mediante ASP.NET Core y proporciona las siguientes operaciones:

Operación Método HTTP Dirección URL relativa Parámetros
Obtener una lista de elementos todo GET /api/todoitems/
Creación de un nuevo elemento todo PUBLICAR /api/todoitems/ Un TodoItem con formato JSON
Actualizar un elemento todo PUT /api/todoitems/ Un TodoItem con formato JSON
Eliminar un elemento todo Delete /api/todoitems/{id}

La aplicación .NET MAUI y el servicio web usan la clase TodoItem para modelar los datos que se muestran y se envían al servicio web para el almacenamiento:

public class TodoItem
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Notes { get; set; }
    public bool Done { get; set; }
}

La propiedad ID se usa para identificar de forma única cada objeto TodoItem y el servicio web usa para identificar los datos que se van a actualizar o eliminar. Por ejemplo, para eliminar el elemento TodoItem cuyo identificador es 6bb8a868-dba1-4f1a-93b7-24ebce87e243, la aplicación .NET MAUI envía una solicitud DELETE a https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243.

Cuando el marco de API web recibe una solicitud, la dirige a una acción. Estas acciones son métodos públicos en la clase TodoItemsController. El marco API Web usa el middleware de enrutamiento para buscar las direcciones URL de las solicitudes entrantes y asignarlas a acciones. Las API REST deben usar el enrutamiento mediante atributos para modelar la funcionalidad de la aplicación como un conjunto de recursos donde las operaciones se representan mediante verbos HTTP. El enrutamiento mediante atributos utiliza un conjunto de atributos para asignar acciones directamente a las plantillas de ruta. Para obtener más información sobre el enrutamiento de atributos, consulta Enrutamiento de atributos para las API REST. Para obtener más información sobre cómo crear el servicio REST mediante ASP.NET Core, consulta Crear servicios back-end para aplicaciones móviles nativas.

Creación del objeto HTTPClient

Una .NET Multi-platform App UI (.NET MAUI) puede consumir un servicio web basado en REST mediante el envío de solicitudes al servicio web con la clase HttpClient. Esta clase proporciona funcionalidad para enviar solicitudes HTTP y recibir respuestas HTTP de un recurso identificado por URI. Cada una de estas solicitudes se envía como una operación asincrónica.

El objeto HttpClient debe declararse a nivel de clase para que resida mientras la aplicación necesite realizar solicitudes HTTP:

public class RestService
{
    HttpClient _client;
    JsonSerializerOptions _serializerOptions;

    public List<TodoItem> Items { get; private set; }

    public RestService()
    {
        _client = new HttpClient();
        _serializerOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };
    }
    ...
}

El objeto JsonSerializerOptions se usa para configurar el formato de la carga JSON que se recibe y se envía al servicio web. Para obtener más información, consulta Creación de instancias de JsonSerializerOptions con System.Text.Json.

Recuperación de datos

El método HttpClient.GetAsync se usa para enviar una solicitud GET al servicio web especificado por el URI y, a continuación, recibir la respuesta del servicio web:

public async Task<List<TodoItem>> RefreshDataAsync()
{
    Items = new List<TodoItem>();

    Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
    try
    {
        HttpResponseMessage response = await _client.GetAsync(uri);
        if (response.IsSuccessStatusCode)
        {
            string content = await response.Content.ReadAsStringAsync();
            Items = JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }

    return Items;
}

Los datos se reciben del servicio web como un objeto HttpResponseMessage. Contiene información sobre la respuesta, incluido el código de estado, los encabezados y cualquier cuerpo. El servicio REST envía un código de estado HTTP en su respuesta, que se puede obtener de la propiedad HttpResponseMessage.IsSuccessStatusCode, para indicar si la solicitud HTTP se realizó correctamente o no. Para esta operación, el servicio REST envía el código de estado HTTP 200 (CORRECTO) en la respuesta, lo que indica que la solicitud se realizó correctamente y que la información solicitada está en la respuesta.

Si la operación HTTP se realizó correctamente, se lee el contenido de la respuesta. La propiedad HttpResponseMessage.Content representa el contenido de la respuesta y es de tipo HttpContent. La clase HttpContent representa el cuerpo HTTP y los encabezados de contenido, como Content-Type y Content-Encoding. A continuación, el contenido se lee en string mediante el método HttpContent.ReadAsStringAsync. A continuación, string se deserializa de JSON a List de objetos TodoItem.

Advertencia

El uso del método ReadAsStringAsync para recuperar una respuesta grande puede tener un impacto negativo en el rendimiento. En tales circunstancias, la respuesta debe deserializarse directamente para evitar tener que almacenarla completamente en búfer.

Crear datos

El método HttpClient.PostAsync se usa para enviar una solicitud POST al servicio web especificado por el URI y, a continuación, para recibir la respuesta del servicio web:

public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
    Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));

    try
    {
        string json = JsonSerializer.Serialize<TodoItem>(item, _serializerOptions);
        StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

        HttpResponseMessage response = null;
        if (isNewItem)
            response = await _client.PostAsync(uri, content);
        else
            response = await _client.PutAsync(uri, content);

        if (response.IsSuccessStatusCode)
            Debug.WriteLine(@"\tTodoItem successfully saved.");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }
}

En este ejemplo, la instancia TodoItem se serializa en una carga JSON para enviar al servicio web. A continuación, esta carga se inserta en el cuerpo del contenido HTTP que se enviará al servicio web antes de realizar la solicitud con el método PostAsync.

El servicio REST envía un código de estado HTTP en su respuesta, que se puede obtener de la propiedad HttpResponseMessage.IsSuccessStatusCode, para indicar si la solicitud HTTP se realizó correctamente o no. Las respuestas típicas para esta operación son:

  • 201 (CREATED): la solicitud dio lugar a que se creara un nuevo recurso antes de enviar la respuesta.
  • 400 (BAD REQUEST): el servidor no entiende la solicitud.
  • 409 (CONFLICT): no se pudo realizar la solicitud debido a un conflicto en el servidor.

Actualizar datos

El método HttpClient.PutAsync se usa para enviar una solicitud PUT al servicio web especificado por el URI y, a continuación, recibir la respuesta del servicio web:

public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
  ...
  response = await _client.PutAsync(uri, content);
  ...
}

La operación del método PutAsync es idéntica al método PostAsync que se usa para crear datos en el servicio web. Sin embargo, las posibles respuestas enviadas desde el servicio web difieren.

El servicio REST envía un código de estado HTTP en su respuesta, que se puede obtener de la propiedad HttpResponseMessage.IsSuccessStatusCode, para indicar si la solicitud HTTP se realizó correctamente o no. Las respuestas típicas para esta operación son:

  • 204 (NO CONTENT): la solicitud se ha procesado correctamente y la respuesta está en blanco intencionadamente.
  • 400 (BAD REQUEST): el servidor no entiende la solicitud.
  • 404 (NOT FOUND): el recurso solicitado no existe en el servidor.

Eliminación de datos

El método HttpClient.DeleteAsync se usa para enviar una solicitud DELETE al servicio web especificado por el URI y, a continuación, recibir la respuesta del servicio web:

public async Task DeleteTodoItemAsync(string id)
{
    Uri uri = new Uri(string.Format(Constants.RestUrl, id));

    try
    {
        HttpResponseMessage response = await _client.DeleteAsync(uri);
        if (response.IsSuccessStatusCode)
            Debug.WriteLine(@"\tTodoItem successfully deleted.");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"\tERROR {0}", ex.Message);
    }
}

El servicio REST envía un código de estado HTTP en su respuesta, que se puede obtener de la propiedad HttpResponseMessage.IsSuccessStatusCode, para indicar si la solicitud HTTP se realizó correctamente o no. Las respuestas típicas para esta operación son:

  • 204 (NO CONTENT): la solicitud se ha procesado correctamente y la respuesta está en blanco intencionadamente.
  • 400 (BAD REQUEST): el servidor no entiende la solicitud.
  • 404 (NOT FOUND): el recurso solicitado no existe en el servidor.

Desarrollo local

Si vas a desarrollar un servicio web REST localmente con un marco como ASP.NET Core Web API, puedes depurar el servicio web y la aplicación .NET MAUI al mismo tiempo. En este escenario, para consumir el servicio web a través de HTTP desde Android Emulators y simuladores de iOS, debes habilitar el tráfico HTTP de texto no cifrado en la aplicación .NET MAUI. Para obtener más información, consulta Conexión a servicios web locales desde simuladores de iOS y Android Emulators.