Para consumir a API de CPF da CPFHub.io em Rust, use a crate reqwest com suporte a JSON e o runtime assíncrono tokio. A chamada é um GET https://api.cpfhub.io/cpf/{CPF} com o header x-api-key, e a resposta retorna nome, data de nascimento e gênero em cerca de 900ms. O serde cuida da desserialização para structs tipadas, tornando a integração segura e previsível.
Introdução
Rust é uma linguagem conhecida por sua segurança de memória e performance excepcional. A crate reqwest é a escolha mais popular para realizar requisições HTTP em Rust, oferecendo uma API ergonômica tanto síncrona quanto assíncrona. Este guia mostra como consumir a API da CPFHub.io usando reqwest com tipagem forte e tratamento robusto de erros.
Configurando o projeto Rust
Crie um novo projeto e adicione as dependências necessárias no Cargo.toml:
// Cargo.toml
[package]
name = "cpf-consulta"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1", features = ["full"] }
A combinação de reqwest para HTTP, serde para serialização e tokio como runtime assíncrono forma a base de qualquer cliente HTTP em Rust.
Definindo as estruturas de dados
Utilize serde para mapear a resposta JSON da API em structs Rust com tipagem forte:
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct CpfResponse {
pub success: bool,
pub data: CpfData,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CpfData {
pub cpf: String,
pub name: String,
pub name_upper: String,
pub gender: String,
pub birth_date: String,
pub day: String,
pub month: String,
pub year: String,
}
| Campo na API | Campo na Struct | Tipo Rust |
|---|---|---|
cpf | cpf | String |
name | name | String |
nameUpper | name_upper | String |
gender | gender | String |
birthDate | birth_date | String |
day | day | String |
month | month | String |
year | year | String |
Realizando a consulta HTTP
Crie uma função assíncrona que realiza a consulta à API com os headers necessários:
use reqwest::header::{HeaderMap, HeaderValue};
use std::error::Error;
async fn consultar_cpf(cpf: &str, api_key: &str) -> Result<CpfResponse, Box<dyn Error>> {
let mut headers = HeaderMap::new();
headers.insert("x-api-key", HeaderValue::from_str(api_key)?);
let client = reqwest::Client::new();
let url = format!("https://api.cpfhub.io/cpf/{}", cpf);
let response = client
.get(&url)
.headers(headers)
.send()
.await?
.error_for_status()?;
let cpf_response = response.json::<CpfResponse>().await?;
Ok(cpf_response)
}
Tratamento de erros idiomático
Em Rust, o tratamento de erros é feito de forma explícita. Crie um tipo de erro customizado para lidar com os diferentes cenários de falha:
use std::fmt;
#[derive(Debug)]
pub enum CpfError {
RequisicaoFalhou(reqwest::Error),
CpfNaoEncontrado,
ChaveInvalida,
ErroDesconhecido(u16),
}
impl fmt::Display for CpfError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CpfError::RequisicaoFalhou(e) => write!(f, "Erro na requisição: {}", e),
CpfError::CpfNaoEncontrado => write!(f, "CPF não encontrado na base"),
CpfError::ChaveInvalida => write!(f, "Chave de API inválida"),
CpfError::ErroDesconhecido(code) => write!(f, "Erro HTTP: {}", code),
}
}
}
impl std::error::Error for CpfError {}
async fn consultar_cpf_seguro(
cpf: &str,
api_key: &str,
) -> Result<CpfResponse, CpfError> {
let mut headers = HeaderMap::new();
headers.insert(
"x-api-key",
HeaderValue::from_str(api_key).map_err(|_| CpfError::ChaveInvalida)?,
);
let client = reqwest::Client::new();
let url = format!("https://api.cpfhub.io/cpf/{}", cpf);
let response = client
.get(&url)
.headers(headers)
.send()
.await
.map_err(CpfError::RequisicaoFalhou)?;
match response.status().as_u16() {
200 => {
let dados = response.json::<CpfResponse>().await
.map_err(CpfError::RequisicaoFalhou)?;
Ok(dados)
}
401 => Err(CpfError::ChaveInvalida),
404 => Err(CpfError::CpfNaoEncontrado),
// Nota: a CPFHub.io não retorna 429; ao superar a cota, cobra R$0,15/consulta extra
code => Err(CpfError::ErroDesconhecido(code)),
}
}
Exemplo completo com Tokio
Monte o programa principal utilizando o runtime tokio:
#[tokio::main]
async fn main() {
let api_key = "SUA_API_KEY";
let cpf = "12345678900";
match consultar_cpf_seguro(cpf, api_key).await {
Ok(resultado) => {
println!("CPF encontrado com sucesso!");
println!(" Nome: {}", resultado.data.name);
println!(" CPF: {}", resultado.data.cpf);
println!(" Nascimento: {}", resultado.data.birth_date);
println!(" Gênero: {}", resultado.data.gender);
}
Err(CpfError::CpfNaoEncontrado) => {
println!("O CPF informado não foi encontrado.");
}
Err(CpfError::ChaveInvalida) => {
println!("Chave de API inválida. Verifique suas credenciais.");
}
Err(e) => {
eprintln!("Erro inesperado: {}", e);
}
}
}
Perguntas frequentes
A CPFHub.io retorna erro 429 quando o limite de consultas é atingido?
Não. A API da CPFHub.io nunca retorna HTTP 429 nem bloqueia requisições. Ao superar a cota mensal (50 no plano gratuito, 1.000 no plano Pro), cada consulta adicional é cobrada automaticamente a R$0,15 — o serviço continua respondendo normalmente. Por isso, o tratamento de erro no código Rust não precisa contemplar esse status.
Como desserializar corretamente o JSON da CPFHub.io em Rust com serde?
Use #[serde(rename_all = "camelCase")] na struct de dados para mapear campos como nameUpper e birthDate automaticamente para name_upper e birth_date. O campo success fica na struct raiz e data é uma struct aninhada. Consulte a documentação do serde para padrões avançados de desserialização.
Qual é o tempo de resposta típico da API ao fazer requisições com reqwest?
A CPFHub.io responde em aproximadamente 900ms. Configure o timeout do cliente reqwest para pelo menos 10 segundos para evitar interrupções em condições normais de rede. Use .timeout(std::time::Duration::from_secs(10)) no builder do cliente.
Como organizar o cliente HTTP em uma aplicação maior em Rust?
Crie um struct CpfClient que encapsula o reqwest::Client e a API key, então registre-o como dado compartilhado (por exemplo, Arc<CpfClient>) entre as tarefas assíncronas. Isso evita criar um novo cliente a cada requisição e garante reutilização do pool de conexões TCP.
Conclusão
Consumir a API de CPF em Rust com reqwest resulta em código performático, seguro e com tratamento de erros explícito. A tipagem forte do Rust, combinada com serde para desserialização, garante que os dados da API sejam manipulados de forma confiável. Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a integrar consultas de CPF em sua aplicação Rust em menos de 30 minutos.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



