Consumir um serviço Web RESTful

Baixar exemplo Baixar o exemplo

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

Normalmente, os serviços Web RESTful 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 código aberto NewtonSoft JSON.NET para serializar e desserializar mensagens.

A simplicidade do REST ajudou a torná-lo o método principal 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, a ATS (Segurança de Transporte de Aplicativo) impõe conexões seguras entre recursos da Internet (como o servidor de back-end do aplicativo) e o aplicativo, impedindo assim a divulgação acidental de informações confidenciais. Como o ATS está habilitado por padrão em aplicativos criados para o 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.

A ATS poderá ser recusada 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 tarefas pendentes POST /api/todoitems/ Um TodoItem formatado em JSON
Atualizar um item pendente PUT /api/todoitems/ Um TodoItem formatado em JSON
Excluir um item pendente Delete (excluir) /api/todoitems/{id}

A maioria dos URIs inclui a TodoItem ID no caminho. Por exemplo, para excluir a TodoItem cuja ID é 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 Web recebe uma solicitação, ela encaminha a solicitação para uma ação. Essas ações são simplesmente métodos públicos na TodoItemsController classe . A estrutura usa o middleware de roteamento para corresponder às URLs das solicitações de entrada e mapeá-las para ações. As APIs REST devem usar o roteamento de atributo do modelo da 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 o roteamento de atributos, consulte Roteamento de atributo para APIs REST. Para obter mais informações sobre como criar o serviço REST usando 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 depois que uma solicitação HTTP é 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 da classe para que o objeto resida enquanto 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 http status 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 HTTP status código 200 (OK) na resposta, o que indica que a solicitação foi bem-sucedida e que as informações solicitadas estão na resposta.

Se a operação HTTP tiver sido bem-sucedida, o conteúdo da resposta será lido para exibição. A HttpResponseMessage.Content propriedade representa o conteúdo da resposta HTTP e o HttpContent.ReadAsStringAsync método grava de forma assíncrona o conteúdo HTTP em uma cadeia de caracteres. Esse conteúdo é então desserializado de JSON para uma List de TodoItem instâncias.

Aviso

Usar o método para recuperar uma resposta grande pode ter um impacto negativo no ReadAsStringAsync desempenho. Nessas circunstâncias, a resposta deve ser desserializada diretamente para evitar ter que fazer um buffer completo.

Criar dados

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 para uma carga JSON para enviar para o serviço Web. Essa carga é então inserida no corpo do conteúdo HTTP que será enviado para o serviço Web antes que a solicitação seja feita com o PostAsync método .

O serviço REST envia um código http status 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 (CREATED) – a solicitação resultou na criação de um novo recurso antes do envio da resposta.
  • 400 (SOLICITAÇÃO INCORRETA) – a solicitação não é compreendida pelo servidor.
  • 409 (CONFLICT) – a solicitação não pôde ser realizada devido a 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 http status 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 êxito e a resposta está intencionalmente em branco.
  • 400 (SOLICITAÇÃO INCORRETA) – a solicitação não é compreendida pelo servidor.
  • 404 (NÃO ENCONTRADO) – o recurso solicitado não existe no servidor.

Excluir 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 http status 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 êxito e a resposta está intencionalmente em branco.
  • 400 (SOLICITAÇÃO INCORRETA) – a solicitação não é compreendida pelo servidor.
  • 404 (NÃO ENCONTRADO) – 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 Core API Web, 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 de iOS e o emulador do Android. Para obter informações sobre como configurar seu projeto para permitir a comunicação, consulte Conectar-se aos serviços Web locais.