Consumir um serviço Web RESTful

A integração de um serviço Web em um aplicativo é um cenário comum. Este artigo demonstra como consumir um serviço Web RESTful de um Xamarin.Forms aplicativo.

REST (Transferência de Estado Representacional) é um estilo de arquitetura para a criação de serviços Web. As solicitações REST são feitas por HTTP usando os mesmos verbos HTTP que os navegadores da Web usam para recuperar páginas da Web e enviar dados para os 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. Esse verbo não é usado no aplicativo de exemplo.
  • DELETE – essa operação é usada para excluir um item de dados no serviço Web.

APIs de serviço Web que aderem ao REST são chamadas de APIs RESTful e 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 RESTful 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. O aplicativo de exemplo usa a biblioteca de JSON.NET NewtonSoft de código aberto para serializar e desserializar mensagens.

A simplicidade do REST ajudou a torná-lo o principal método para acessar serviços Web em aplicativos móveis.

Quando o aplicativo de exemplo for executado, ele se conectará a um serviço REST hospedado localmente, conforme mostrado na captura de tela a seguir:

Aplicativo de exemplo

Observação

No iOS 9 e superior, o App Transport Security (ATS) impõe conexões seguras entre recursos da Internet (como o servidor back-end do aplicativo) e o aplicativo, evitando assim a divulgação acidental de informações confidenciais. Como o ATS está habilitado por padrão em aplicativos criados para iOS 9, todas as conexões estarão sujeitas aos requisitos de segurança do ATS. Se as conexões não atenderem a esses requisitos, elas falharão com uma exceção.

O ATS pode ser desativado se não for possível usar o protocolo HTTPS e a comunicação segura para recursos da Internet. Isso pode ser feito atualizando o arquivo Info.plist do aplicativo. Para obter mais informações, consulte Segurança de transporte de aplicativo.

Consumir o serviço Web

O serviço REST é 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 pendentes GET /api/todoitems/
Criar um novo item de tarefa pendente POSTAR /api/todoitems/ Um TodoItem formatado em JSON
Atualizar um item pendente PUT /api/todoitems/ Um TodoItem formatado em JSON
Excluir um item pendente DELETE /api/todoitems/{id}

A maioria dos URIs inclui a TodoItem ID no caminho. Por exemplo, para excluir o TodoItem ID cujo é 6bb8a868-dba1-4f1a-93b7-24ebce87e243, o cliente envia uma solicitação DELETE para http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243. Para obter mais informações sobre o modelo de dados usado no aplicativo de exemplo, consulte Modelando os dados.

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 simplesmente métodos públicos na TodoItemsController classe. A estrutura 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, o modelo, 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.

A HttpClient classe é usada para enviar e receber solicitações por HTTP. Ele 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. Para obter mais informações sobre operações assíncronas, consulte Visão geral do suporte assíncrono.

A HttpResponseMessage classe representa uma mensagem de resposta HTTP recebida do serviço Web após uma solicitação HTTP ter sido feita. Ela contém informações sobre a resposta, incluindo o código de status, cabeçalhos e qualquer corpo. A HttpContent classe representa o corpo HTTP e os cabeçalhos de conteúdo, como Content-Type e Content-Encoding. O conteúdo pode ser lido usando qualquer um dos ReadAs métodos, como ReadAsStringAsync e ReadAsByteArrayAsync, dependendo do formato dos dados.

Criar o objeto HTTPClient

A HttpClient instância é declarada no nível de classe para que o objeto viva pelo tempo que o aplicativo precisar fazer solicitações HTTP, conforme mostrado no exemplo de código a seguir:

public class RestService : IRestService
{
  HttpClient client;
  ...

  public RestService ()
  {
    client = new HttpClient ();
    ...
  }
  ...
}

Recuperar dados

O HttpClient.GetAsync método é usado para enviar a solicitação GET para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço Web, conforme mostrado no exemplo de código a seguir:

public async Task<List<TodoItem>> RefreshDataAsync ()
{
  ...
  Uri uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
  ...
  HttpResponseMessage response = await client.GetAsync (uri);
  if (response.IsSuccessStatusCode)
  {
      string content = await response.Content.ReadAsStringAsync ();
      Items = JsonSerializer.Deserialize<List<TodoItem>>(content, serializerOptions);
  }
  ...
}

O serviço REST envia um código de status HTTP na 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, para exibição. A HttpResponseMessage.Content propriedade representa o conteúdo da resposta HTTP e o método grava HttpContent.ReadAsStringAsync de forma assíncrona o conteúdo HTTP em uma cadeia de caracteres. Esse conteúdo é então desserializado de JSON para uma List das TodoItem instâncias.

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 a solicitação POST para o serviço Web especificado pelo URI e, em seguida, para receber a resposta do serviço Web, conforme mostrado no exemplo de código a seguir:

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

  ...
  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);
  }
  ...

  if (response.IsSuccessStatusCode)
  {
    Debug.WriteLine (@"\tTodoItem successfully saved.");
  }
  ...
}

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 na HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas comuns 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 a solicitação PUT para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço Web, conforme mostrado no exemplo de código a seguir:

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 na HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas comuns 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 a solicitação DELETE para o serviço Web especificado pelo URI e, em seguida, receber a resposta do serviço Web, conforme mostrado no exemplo de código a seguir:

public async Task DeleteTodoItemAsync (string id)
{
  Uri uri = new Uri (string.Format (Constants.TodoItemsUrl, id));
  ...
  HttpResponseMessage response = await client.DeleteAsync (uri);
  if (response.IsSuccessStatusCode)
  {
    Debug.WriteLine (@"\tTodoItem successfully deleted.");
  }
  ...
}

O serviço REST envia um código de status HTTP na HttpResponseMessage.IsSuccessStatusCode propriedade, para indicar se a solicitação HTTP foi bem-sucedida ou falhou. As respostas comuns 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 seu serviço Web REST localmente com uma estrutura como ASP.NET API Web Core, poderá depurar seu serviço Web e aplicativo móvel ao mesmo tempo. Nesse cenário, você deve habilitar o tráfego HTTP de texto não criptografado para o simulador iOS e emulador Android. Para obter informações sobre como configurar seu projeto para permitir a comunicação, consulte Conectar-se a serviços Web locais.