Como Consumir API Restful no Xamarin Forms

O objetivo é exemplificar passo a passo como consumir serviços Restful API no Xamarin Forms de forma manual para entendimento.

Eu utilizei o Visual Studio 2015 Community para criar o código fonte de Cross Platform Xamarin Forms. Caso não saiba o que é Xamarin Forms, encorajo você a ler meu artigo Xamarin Forms: Um Código para Controlar Todos os Outros.

Você poderá usar o Visual Studio 2017 se preferir, mas dê uma olhada no UNBOXING VS2017 que escrevi com minhas primeiras impressões da nova IDE e decida se realmente precisa usar o 2017.

 
Como Consumir API Restful no Xamarin Forms
 


 

Bom, chega de conversa. As premissas para este artigo são as seguintes:

  • Criar uma aplicação ASP.NET Web API para servir como serviço Restful.
  • Criar um projeto Cross Platform Xamarin Forms (portable, iOS e Android).
  • Fazer o Xamarin Forms se comunicar com o serviço Web API.
  • Os dados da API serão exibidos em um ListView tela no Xamarin Forms.

Fácil? Por enquanto acho que sim.

Bom, vai lá e crie um novo projeto Cross Platform Xamarin Forms no Visual Studio 2015 usando o menu File / New / Project. Certifique-se que esteja dentro de ASP.NET 4.5.1 ou 4.5.2.

 
Como Consumir API Restful no Xamarin Forms
 

O template do Visual Studio irá criar uma solution com 5 projetos dentro, um iOS, um Android, um Class Library “portable” e outros 2 para Windows phone. Por favor, delete os dois projetos de Windows phone pois não fazem parte das premissas e também não preparei o código fonte para funcionar com eles.

Com o projeto criado sugiro o seguinte:

1 – Nas propriedades do projeto Android, em Android Options / Advanced configure o 1G no Java Max Heap Size.

Java Max Heap Size serve para configurar o tamanho máximo de memória que será usado para compilar o projeto Android


 

 
Como Consumir API Restful no Xamarin Forms
 

2 – Atualize a versão do Xamarin Forms de cada projeto (iOS, Android e Portable) para 2.3.0.107.

 
Como Consumir API Restful no Xamarin Forms
 

3 – Ainda nas propriedades do Android, configure para funcionar com API 23, pois alguns problemas de compilação podem ocorrer se não explicitar essa API.

 
Como Consumir API Restful no Xamarin Forms
 

Você está sem paciência para fazer toda essa configuração? Eu entendo! Então faz o seguinte: acesse meu repositório no Github e faça download do código e aproveite para me seguir lá 🙂

MAS… sugiro que você continue lendo o artigo para um melhor entendimento.

Quando eu escrevi o artigo Consumindo Serviços ASMX com Xamarin Forms, percebi que logo logo seria necessário escrever um artigo exclusivo para consumir Restful API, pois então, após pedidos da comunidade, em especial de Larissa Medeiros, segue o passo a passo para a solução.

Crie um ListView via XAML no arquivo MainPage.xaml.

XAML é uma linguagem de marcação utilizada para criar telas no Xamarin Forms, Windows Presentation Foundation, Silverlight e outros. Fazendo uma analogia, parece muito com XML.


 

<ListView x:Name="lvCustomers" VerticalOptions="Center" HorizontalOptions="Center">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="{Binding Name}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Quando comecei a trabalhar com Xamarin Forms, decidi escrever sobre meu dia a dia trabalhando com essa tecnologia, e no Xamarin Wars: Uma Nova Esperança Mobile, uma das coisas mais interessantes foi a possibilidade do compartilhamento de código entre as plataformas iOS e Android, principalmente o compartilhamento das telas.

Por isso não há necessidade de fazer mais nada além da tela MainPage.xml. O foco não é usar nenhum Design Patterns no Xamarin Forms, apenas popular o ListView com os dados da API.

Agora no código C#, crie uma classe de nome ApiClient , ela será responsável por consumir qualquer serviço Restful API, inclusive o ASP.NET Web API. Se preferir, baixe o código fonte completo no meu repositório no Github.

public class ApiClient : IApiClient
    {
        public async Task<BaseApiResult<TModel>> GetAsync<TModel>(string apiRoute, Action<BaseApiResult<TModel>> callback = null)
        {
            try
            {
                var json = await GetAsync(apiRoute);
                var data = JsonConvert.DeserializeObject<TModel>(json, GetConverter());
                var result = new OkApiResult<TModel>(data);

                callback?.Invoke(result);

                return result;
            }
            catch (Exception ex)
            {
                return new InvalidApiResult<TModel>(ex);
            }
        }

        private async Task<string> GetAsync(string apiRoute)
        {
            var url = _apiUrlBase + "/" + apiRoute;

            _restClient = _restClient ?? new HttpClient();
            _restClient.BaseAddress = new Uri(url);

            ClearReponseHeaders();
            AddReponseHeaders();

            var response = await _restClient.GetAsync(_restClient.BaseAddress);
            response.EnsureSuccessStatusCode();
            var data = response.Content.ReadAsStringAsync().Result;

            return data;
        }
    }

Observação: Necessário instalar o pacote Microsoft.Net.Http e Newtonsoft.Json através no Nuget Package Manager.

A classe ApiClient é genérica, ou seja, pode ser usada com qualquer API Restful. Basicamente ela recebe uma URL, faz um solicitação (request) nessa URL e converte o resultado (string JSON) para a classe escolhida.

Por fim, o resultado convertido é encapsulado em outra classe OkApiResult que contém propriedades que guardam informações do request, como por exemplo, se a solicitação foi realizada com sucesso, mensagens de erros e outras coisas.

Eu Apoio Fabio Silva Lima


 

Para esse artigo, a classe ApiClient funcionará apenas com protocolo GET. Futuramente podemos implementar outros métodos conforme a necessidade, inclusive uso de Cache. Ah! Por falar em cache, dá uma olhada em Como Chamar Cache Provider em Uma Linha de Código no C#.

Último passo é chamar o método GetAllCustomers que irá popular o ListView no MainPage.xaml:

protected override async void OnAppearing()
        {
            base.OnAppearing();
            var result = await _customerApiClient.GetAllCustomers();
            if (result.Success)
            {
                lvCustomers.ItemsSource = result.Data;
            }
        }

A implementação da classe que traz todos os clientes da API é a CustomersApiClient:

public sealed class CustomersApiClient : ApiClient, ICustomersApiClient
    {
        public CustomersApiClient() 
            : base("http://10.0.2.2/FSL.XFApi/api")
        {

        }

        public async Task<BaseApiResult<List<Customer>>> GetAllCustomers()
        {
            return await FslApiClient.Current.GetAsync<List<Customer>>("customers");
        }
    }

Como podem ver no código acima, a chamada genérica do ApiClient é realizada dentro do método GetAllCustomers. Eu criei uma classe FslApiClient para usar como Singleton para que a instância da API fique disponível sempre que for chamado dessa forma: FslApiClient.Current.

Singleton FslApiClient:

public sealed class CustomersApiClient : ApiClient, ICustomersApiClient
    public sealed class FslApiClient
    {
        private static volatile ICustomersApiClient _instance;
        private static object syncRoot = new object();
        
        public static ICustomersApiClient Current
        {
            get
            {
                if (_instance == null)
                {
                    lock (syncRoot)
                    {
                        _instance = new CustomersApiClient(); // You can use Dependency Injection
                    }
                }

                return _instance;
            }
        }
    }

Depois de compilar o código, pode ser que demore um tempo, quando executar a aplicação usando o emulador do Android deverá aparecer uma tela parecida com esta:

 

 

No Xamarin Forms, para os serviços ASP.NET Web API que estejam hospedados localmente (localhost) os mesmos devem ser chamados através do IP http://10.0.2.2/, caso contrário os emuladores não entendem.


 

Considerações finais:

Uma alternativa no XAML MainPage.xaml da tela seria usar o Design Pattern MVVM (Model-View-View-Model) para popular o ListView ao invés do que fizemos neste artigo.

Outra coisa que poderíamos melhorar seria usar Dependency Injection para receber a instância de CustomerApiClient.

O intuito do artigo não é baixar um plugin ou componente que faz acesso a API Restful e sim criar manualmente essa chamada para entendermos o funcionamento por completo.

E aí? O que achou deste artigo? Fácil ou difícil?

Deixe seu comentário, ajude a aprimorar este conteúdo entrando em contato aqui.

Como Consumir API Restful no Xamarin Forms

API RESTFUL: Perguntas, sugestões ou críticas são bem vindas. Boa sorte!

Sobre o Autor:
Trabalha como arquiteto de soluções e desenvolvedor, tem mais de 18 anos de experiência em desenvolvimento de software em diversas plataformas sendo mais de 16 anos somente para o mercado de seguros.
Revisado por:
Apaixonado por tecnologia e sempre disposto a encarar novos desafios, atualmente trabalho focado em aplicações web e mobile com a plataforma .NET, e me aventurando nas diversas linguagens, desafios e experiências que a área nos proporciona.