Criando o Client

O cliente é parte que cuidará de sua integração. Terá todas as configurações necessárias para conseguirmos nos conectar a um serviço. Também teremos algumas estratégias como politica de Retry e Cache. Ele vai ser nosso contexto para o serviço. Fazendo assim, deixando as coisas mais organizadas.

Vamos do início. Precisamos criar nosso cliente para se comunicar com o SampleApis, um serviço de exemplos de APIs que estamos usando como base em nossos estudos. Ele será responsável em realizar a requisição ao serviço e trazer os dados. Também irá lidar com possíveis erros.

Em nosso primeiro exemplo, queremos trazer a lista do elixir da vida, também chamado de cafézinho quente. Para isso precisamos saber onde estamos pisando.

Vamos fazer uma lista de objetivos. Gosto de listas bem definidas.

O serviço a ser usado encontrasse na URL https://api.sampleapis.com/coffee/hot, e seu verbo HTTP é GET. Isso quer dizer, se você abrir esse link em seu navegador você vai ver uma lista de itens no formato em JSON de cafezinhos quente, como vimos nesse exemplo.

Agora precisamos delegar essa ação para o Tesla. Nossa lista de tarefa então será

  • Obter lista de cafés quentes

  • Testar resposta de sucesso com os cafés quentes

Implementação

Criaremos um novo arquivo dentro de uma pasta integrations. Esse será a pasta do contexto de integrações. Tudo referente a ele viverá ali. Seguirei a ideia de Screaming Archtecture para ter um norte.

mkdir lib/coffee_shop/integrations/coffee

Em sua pasta, criamos um arquivo chamado client.ex referente ao cliente do serviço.

lib/coffee_shop/integrations/coffee/client.ex
defmodule CoffeeShop.Integrations.Coffee.Client do
 
end

Nele vamos criar nossa função de requisição, chamarei ela de all_hot_coffees/0

lib/coffee_shop/integrations/coffee/client.ex
defmodule CoffeeShop.Integrations.Coffee.Client do
  def all_hot_coffees do
  
  end
end

Agora precisamos entender onde devemos requisitar o serviço

Vamos traduzir isso para código.

Precisamos que o tesla execute uma chamada GET para esse recurso. O Tesla possui funçoes de acordo com o verbo que precisamos Tesla.post/2, Tesla.get/1, Tesla.delete/1 e Tesla.put/2 . Obviametne, precisamos do Tesla.get/1 onde seu parâmetro é o recurso que iremos requisitar, sendo https://api.sampleapis.com/coffee/hot.

Uma boa leitura vindo do nosso requisito, certo? Vamos colocar esse código para funcionar.

Perfeito. Uma coisa que tenho que te falar. Tesla possui o conceito de middlewares. Eles são comportamentos que executam antes de um requisição acontecer. Podemos usar ele para simplificar um pouco o código. Como por exemplo, configurar nossa url base, ao invez de colocar tudo diretamente na função. Para conseguir usar os middlewares de forma limpa, podemos usar uma macro do Tesla e transformar nosso Client em um Tesla.Client. Isso cria uma dependência direta. Não gosto muito disso, mas iremos por esse lado para explorar todo o potencial do Tesla. Com a macro, podemos utilizar plug para configurar os middlewares e utilizaremos o middleware BaseUrl. Com a macro e o middleware, podemos remover um pouco de codigo.

Nossa função ficou mais simples. Vamos continuar assim por um tempo. Com tudo devidamente configurado, podemos rodar nossa função de requisição pelo terminal iterativo. Acesse o terminal.

Chame a função croiada diretamente.

Que coisa linda não? Você fez sua primeira requisição a um serviço externo programaticamente. Você consegue ver a lista de cafés e usar em sua aplicação. Para confirmar que tudo está vindo como queremos, você pode ir no atributo body e notará que tem uma resposta em JSON.

Muito mais fácil que você imaginava não? Porém, ainda temos alguns objetivos

  • Obter lista de cafés quentes

  • Testar a resposta de sucesso com os cafés

Teste

Estamos usando um serviço externo para obter dados. Isso nos poupa tempo em relação a desenvolver uma solução. Mas precisamos garantir que nossa implementação sempre venha a funcionar. Para isso, podemos realizar testes programaticamente.

Iremos criar nosso arquivo de teste replicando o caminho da implementação e adicionaremos a base para nossos cenários a serem cobertos.

Estamos utilizando o ExUnit para nossos testes e com ele, vamos criar nossas afirmações:

Rodando o teste

Precisamos também garantir que a resposta seja um Tesla.Env, estrutura que o Tesla devolve em suas respostas. Vamos adicionar ao nosso teste.

Conclusão

Nosso primeiro test esta funcionando, isso quer dizer, menos um item na lista. Fácil não? Para que um livro desse? =D

  • Obter dados quando a resposta for um sucesso

  • Tratar resposta quando a resposta for um erro

  • Devemos ter acesso fácil a lista de cafés

Nosso próximo passo é testar o comportamento quando a resposta de nosso serviço volta um erro. A pergunta mais comum aqui é, como diabos eu farei gerar um erro nisso se o serviço não é meu?

Hora do mock.

Atualizado

Isto foi útil?