Consumir um serviço Web baseado em REST

Browse sample. Navegue pelo exemplo

REST (Transferência de Estado Representacional) é um estilo de arquitetura para a criação de serviços Web. As solicitações REST geralmente são feitas por HTTPS usando os mesmos verbos HTTP que os navegadores da Web usam para recuperar páginas da Web e enviar dados para servidores. Os verbos são:

  • GET – essa operação é usada para recuperar dados do serviço Web.
  • POST – essa operação é usada para criar um item de dados no serviço Web.
  • PUT – essa operação é usada para atualizar um item de dados no serviço Web.
  • PATCH – essa operação é usada para atualizar um item de dados no serviço Web, descrevendo um conjunto de instruções sobre como o item deve ser modificado.
  • DELETE – essa operação é usada para excluir um item de dados no serviço Web.

As APIs de serviço Web que aderem ao REST são definidas usando:

  • Um URI de base.
  • Métodos HTTP, como GET, POST, PUT, PATCH ou DELETE.
  • Um tipo de mídia para os dados, como JSON (JavaScript Object Notation).

Os serviços Web baseados em REST normalmente usam mensagens JSON para retornar dados ao cliente. JSON é um formato de intercâmbio de dados baseado em texto que produz cargas compactas, o que resulta em requisitos de largura de banda reduzidos ao enviar dados. A simplicidade do REST ajudou a torná-lo o principal método para acessar serviços Web em aplicativos móveis.

Observação

O acesso a um serviço Web geralmente requer programação assíncrona. Para obter mais informações sobre programação assíncrona, consulte Programação assíncrona com assíncrona e await.

Operações de serviço Web

O serviço REST de exemplo é escrito usando ASP.NET Core e fornece as seguintes operações:

Operação Método HTTP URI relativo Parâmetros
Obter uma lista de itens de todo GET /api/todoitems/
Criar um novo item de todo POST /api/todoitems/ Um TodoItem formatado em JSON
Atualizar um item de todo PUT /api/todoitems/ Um TodoItem formatado em JSON
Excluir um item de todo DELETE /api/todoitems/{id}

O aplicativo .NET MAUI e o serviço Web usam a TodoItem classe para modelar os dados exibidos e enviados ao serviço Web para armazenamento:

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

A ID propriedade é usada para identificar exclusivamente cada TodoItem objeto e é usada pelo serviço Web para identificar dados a serem atualizados ou excluídos. Por exemplo, para excluir a TodoItem ID cujo é 6bb8a868-dba1-4f1a-93b7-24ebce87e243, o aplicativo .NET MAUI envia uma solicitação DELETE para https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243.

Quando a estrutura da API da Web recebe uma solicitação, ela roteia a solicitação para uma ação. Essas ações são métodos públicos na TodoItemsController classe. A estrutura da API da Web usa middleware de roteamento para corresponder às URLs de solicitações de entrada e mapeá-las para ações. As APIs REST devem usar o roteamento de atributos para modelar a funcionalidade do aplicativo como um conjunto de recursos cujas operações são representadas por verbos HTTP. O roteamento de atributo usa um conjunto de atributos para mapear ações diretamente para modelos de rota. Para obter mais informações sobre roteamento de atributos, consulte Roteamento de atributos para APIs REST. Para obter mais informações sobre como criar o serviço REST usando o ASP.NET Core, consulte Criando serviços de back-end para aplicativos móveis nativos.

Criar o objeto HTTPClient

Um aplicativo .NET Multi-platform App UI (.NET MAUI) pode consumir um serviço Web baseado em REST enviando solicitações para o serviço Web com a HttpClient classe. Essa classe fornece funcionalidade para enviar solicitações HTTP e receber respostas HTTP de um recurso identificado por URI. Cada solicitação é enviada como uma operação assíncrona.

O HttpClient objeto deve ser declarado no nível de classe para que ele viva pelo tempo que o aplicativo precisar fazer solicitações 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
        };
    }
    ...
}

O JsonSerializerOptions objeto é usado para configurar a formatação da carga JSON recebida e enviada ao serviço Web. Para obter mais informações, consulte Como instanciar instâncias JsonSerializerOptions com System.Text.Json.

Recuperar dados

O HttpClient.GetAsync método é usado para enviar uma solicitação GET para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço 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;
}

Os dados são recebidos do serviço Web como um HttpResponseMessage objeto. Ela contém informações sobre a resposta, incluindo o código de status, cabeçalhos e qualquer corpo. O serviço REST envia um código de status HTTP em sua resposta, que pode ser obtido da HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. Para essa operação, o serviço REST envia o código de status HTTP 200 (OK) na resposta, que indica que a solicitação foi bem-sucedida e que as informações solicitadas estão na resposta.

Se a operação HTTP foi bem-sucedida, o conteúdo da resposta é lido. A HttpResponseMessage.Content propriedade representa o conteúdo da resposta e é do tipo HttpContent. A HttpContent classe representa o corpo HTTP e os cabeçalhos de conteúdo, como Content-Type e Content-Encoding. O conteúdo é então lido em um string usando o HttpContent.ReadAsStringAsync método. O string é então desserializado de JSON para um List de TodoItem objetos.

Aviso

Usar o ReadAsStringAsync método para recuperar uma resposta grande pode ter um impacto negativo no desempenho. Em tais circunstâncias, a resposta deve ser diretamente desserializada para evitar ter que armazená-la totalmente em buffer.

Criar fluxo de

O HttpClient.PostAsync método é usado para enviar uma solicitação POST para o serviço Web especificado pelo URI e, em seguida, para receber a resposta do serviço 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);
    }
}

Neste exemplo, a TodoItem instância é serializada em uma carga JSON para envio ao serviço Web. Essa carga é então incorporada no corpo do conteúdo HTTP que será enviado ao serviço Web antes que a solicitação seja feita com o PostAsync método.

O serviço REST envia um código de status HTTP em sua resposta, que pode ser obtido da HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas típicas para esta operação são:

  • 201 (CRIADO) – a solicitação resultou na criação de um novo recurso antes do envio da resposta.
  • 400 (BAD REQUEST) – o pedido não é compreendido pelo servidor.
  • 409 (CONFLITO) – o pedido não pôde ser realizado por causa de um conflito no servidor.

Atualizar dados

O HttpClient.PutAsync método é usado para enviar uma solicitação PUT para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço Web:

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

A operação do PutAsync método é idêntica ao PostAsync método usado para criar dados no serviço Web. No entanto, as possíveis respostas enviadas do serviço Web diferem.

O serviço REST envia um código de status HTTP em sua resposta, que pode ser obtido da HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas típicas para esta operação são:

  • 204 (SEM CONTEÚDO) – a solicitação foi processada com sucesso e a resposta está intencionalmente em branco.
  • 400 (BAD REQUEST) – o pedido não é compreendido pelo servidor.
  • 404 (NOT FOUND) – o recurso solicitado não existe no servidor.

Excluir os dados

O HttpClient.DeleteAsync método é usado para enviar uma solicitação DELETE para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço 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);
    }
}

O serviço REST envia um código de status HTTP em sua resposta, que pode ser obtido da HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas típicas para esta operação são:

  • 204 (SEM CONTEÚDO) – a solicitação foi processada com sucesso e a resposta está intencionalmente em branco.
  • 400 (BAD REQUEST) – o pedido não é compreendido pelo servidor.
  • 404 (NOT FOUND) – o recurso solicitado não existe no servidor.

Desenvolvimento local

Se você estiver desenvolvendo um serviço Web REST localmente com uma estrutura como ASP.NET API Web Core, poderá depurar seu serviço Web e o aplicativo .NET MAUI ao mesmo tempo. Nesse cenário, para consumir seu serviço Web sobre HTTP de emuladores Android e simuladores iOS, você deve habilitar o tráfego HTTP de texto não criptografado em seu aplicativo .NET MAUI. Para obter mais informações, consulte Conectar-se a serviços Web locais a partir de emuladores Android e simuladores iOS.