# Como consumir a API de CPF em Elixir usando HTTPoison e Tesla

> Aprenda a consumir a API de consulta de CPF em Elixir usando as bibliotecas HTTPoison e Tesla com exemplos práticos.

**Publicado:** 12/11/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-cpf-elixir-httpoison-tesla

---


Elixir oferece duas bibliotecas principais para consumir a API de CPF da CPFHub.io: HTTPoison, baseada em hackney, e Tesla, com seu sistema de middlewares plugáveis. Ambas realizam chamadas `GET https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key` e retornam o JSON com nome, data de nascimento e gênero do titular. A escolha entre elas depende do nível de composição necessário — o HTTPoison é mais direto, o Tesla oferece retry, logging e testabilidade com mock adapter nativo.

## Introdução

Elixir oferece um ecossistema rico para comunicação HTTP, com duas bibliotecas principais: HTTPoison, baseada em hackney, e Tesla, que utiliza um sistema de middlewares plugáveis. Este artigo mostra como consumir a API da CPFHub.io utilizando ambas as abordagens, comparando suas características e ajudando você a escolher a melhor para cada cenário. A documentação oficial do HTTPoison está em [hexdocs.pm/httpoison](https://hexdocs.pm/httpoison) e a do Tesla em [hexdocs.pm/tesla](https://hexdocs.pm/tesla).

---

## Configurando o projeto

Crie um novo projeto Elixir e adicione as dependências:

```elixir
# mix.exs
defp deps do
 [
 {:httpoison, "~> 2.0"},
 {:tesla, "~> 1.8"},
 {:hackney, "~> 1.20"},
 {:jason, "~> 1.4"}
 ]
end
```

Execute `mix deps.get` para baixar as dependências. Ambas as bibliotecas suportam requisições assíncronas e tratamento de erros robusto.

---

## Consumindo com HTTPoison

O HTTPoison é a biblioteca HTTP mais popular do Elixir. A consulta à API fica direta e concisa:

```elixir
defmodule CpfHub.HTTPoisonClient do
 @base_url "https://api.cpfhub.io"

 def consultar(cpf, api_key) do
 headers = [
 {"x-api-key", api_key},
 {"Content-Type", "application/json"}
 ]

 case HTTPoison.get("#{@base_url}/cpf/#{cpf}", headers) do
 {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
 {:ok, Jason.decode!(body)}

 {:ok, %HTTPoison.Response{status_code: 401}} ->
 {:error, :chave_invalida}

 {:ok, %HTTPoison.Response{status_code: 404}} ->
 {:error, :cpf_nao_encontrado}

 {:ok, %HTTPoison.Response{status_code: status}} ->
 {:error, {:status_inesperado, status}}

 {:error, %HTTPoison.Error{reason: reason}} ->
 {:error, {:falha_rede, reason}}
 end
 end
end
```

---

## Consumindo com Tesla

O Tesla oferece uma abordagem baseada em middlewares que permite compor funcionalidades como retry, logging e encoding de forma declarativa:

```elixir
defmodule CpfHub.TeslaClient do
 use Tesla

 plug Tesla.Middleware.BaseUrl, "https://api.cpfhub.io"
 plug Tesla.Middleware.JSON
 plug Tesla.Middleware.Headers, [{"x-api-key", "SUA_API_KEY"}]
 plug Tesla.Middleware.Retry, delay: 1000, max_retries: 3
 plug Tesla.Middleware.Logger

 def consultar(cpf) do
 case get("/cpf/#{cpf}") do
 {:ok, %Tesla.Env{status: 200, body: body}} ->
 {:ok, body}

 {:ok, %Tesla.Env{status: 401}} ->
 {:error, :chave_invalida}

 {:ok, %Tesla.Env{status: 404}} ->
 {:error, :cpf_nao_encontrado}

 {:ok, %Tesla.Env{status: status}} ->
 {:error, {:status_inesperado, status}}

 {:error, reason} ->
 {:error, {:falha_requisicao, reason}}
 end
 end
end
```

**Nota:** a API da CPFHub.io nunca retorna HTTP 429. Ao atingir o limite mensal do plano, as consultas adicionais são cobradas a R$0,15 cada — sem bloqueio, sem interrupção de serviço. O middleware `Retry` acima é útil para erros de rede transitórios, não para limite de cota.

---

## Comparação entre HTTPoison e Tesla

A escolha entre as duas bibliotecas depende das necessidades do projeto:

| Característica | HTTPoison | Tesla |
|---|---|---|
| Base | hackney | Plugável (hackney, Mint, etc.) |
| Middlewares | Não possui | Sistema completo de middlewares |
| Retry built-in | Não | Sim (via middleware) |
| Logging built-in | Não | Sim (via middleware) |
| Testabilidade | Mock manual | Mock adapter nativo |
| Comunidade | Mais estabelecida | Crescendo rapidamente |
| API | Mais baixo nível | Mais alto nível |

---

## Criando um módulo unificado

Para flexibilidade, crie um behaviour que permite trocar a implementação HTTP:

```elixir
defmodule CpfHub.Client do
 @callback consultar(cpf :: String.t()) :: {:ok, map()} | {:error, atom()}

 def new(api_key) do
 %{api_key: api_key}
 end

 def consultar_cpf(%{api_key: api_key}, cpf) do
 cpf_limpo = String.replace(cpf, ~r/\D/, "")

 if String.length(cpf_limpo) != 11 do
 {:error, :formato_invalido}
 else
 CpfHub.HTTPoisonClient.consultar(cpf_limpo, api_key)
 end
 end
end

# Uso
client = CpfHub.Client.new("SUA_API_KEY")

case CpfHub.Client.consultar_cpf(client, "123.456.789-00") do
 {:ok, %{"success" => true, "data" => dados}} ->
 IO.puts("Nome: #{dados["name"]}")
 IO.puts("CPF: #{dados["cpf"]}")
 IO.puts("Nascimento: #{dados["birthDate"]}")
 IO.puts("Gênero: #{dados["gender"]}")

 {:error, :cpf_nao_encontrado} ->
 IO.puts("CPF não encontrado na base")

 {:error, :chave_invalida} ->
 IO.puts("Verifique sua chave de API")

 {:error, reason} ->
 IO.puts("Erro: #{inspect(reason)}")
end
```

---

## Perguntas frequentes

### Qual biblioteca devo escolher para integrar a API de CPF em Elixir: HTTPoison ou Tesla?

Prefira o Tesla se o projeto já usa middleware de retry, logging centralizado ou precisa de mocks em testes. O HTTPoison é a escolha certa quando você quer uma integração simples, sem dependências extras de composição — basta um `case` no status code e você tem controle total. Ambos funcionam bem com a API da CPFHub.io.

### Como testar a integração com a API de CPF sem fazer chamadas reais em Elixir?

Com Tesla, use `Tesla.Mock` no ambiente de teste: configure `adapter: Tesla.Mock` no módulo cliente e defina as respostas esperadas com `Tesla.Mock.mock/1`. Com HTTPoison, injete um módulo de adapter via configuração de ambiente (`config :minha_app, :http_client, MyMockClient`) e implemente um comportamento compartilhado entre o cliente real e o mock.

### A API da CPFHub.io retorna HTTP 429 quando o limite do plano é atingido?

Não. A API da CPFHub.io nunca bloqueia nem retorna HTTP 429. Quando o limite mensal de consultas é ultrapassado, as requisições adicionais são processadas normalmente e cobradas a R$0,15 cada. Isso simplifica o tratamento de erros na sua aplicação Elixir — não é necessário implementar lógica de backoff para cota esgotada.

### Como usar Oban para processar consultas de CPF em background no Elixir?

Crie um worker Oban que recebe o CPF e chama o `CpfHub.Client.consultar_cpf/2`. Configure a fila com concorrência adequada e use `Oban.insert/1` nos pontos de entrada do sistema (cadastro de usuário, por exemplo). O Oban garante retry automático em caso de falha de rede, persistência no banco e visibilidade dos jobs via dashboard.

### Leia também

- [Como criar um microsserviço de validação de CPF com Elixir e Phoenix](https://cpfhub.io/blog/como-criar-microsservico-validacao-cpf-elixir-phoenix)
- [Como integrar a API de CPF em uma aplicação Phoenix](https://cpfhub.io/blog/como-integrar-api-cpf-aplicacao-phoenix)
- [Como validar CPF em tempo real usando Elixir e APIs REST](https://cpfhub.io/blog/como-validar-cpf-tempo-real-elixir-apis-rest)
- [Como usar Oban para processar consultas de CPF em background no Elixir](https://cpfhub.io/blog/como-usar-oban-processar-consultas-cpf-background-elixir)

---

## Conclusão

Tanto HTTPoison quanto Tesla são opções sólidas para consumir a API de CPF em Elixir. O HTTPoison é ideal para projetos que precisam de controle fino sobre as requisições, enquanto o Tesla brilha com seu sistema de middlewares e facilidade de teste.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a consultar CPFs na sua aplicação Elixir com a biblioteca que melhor se encaixa no seu stack.

