Você já precisou integrar um app com dados de terceiros — previsão do tempo, pagamentos, mapas — e se perdeu no meio de URLs e respostas JSON? Uma API REST resolve isso, permitindo que sistemas conversem de forma padronizada. Neste post, você vai deixar a teoria de lado e aprender a consumir APIs REST com exemplos funcionais em Python, JavaScript e Java.
O que é uma API REST (sem enrolação)
REST (Representational State Transfer) é um conjunto de princípios arquiteturais. Na prática, significa: você usa URLs para acessar recursos (ex.: /usuarios) e métodos HTTP para executar ações. Os quatro principais são:
- GET — buscar dados (não muda estado)
- POST — criar um novo recurso
- PUT — atualizar um recurso existente (geralmente, o conjunto todo)
- DELETE — remover um recurso
O retorno — na maioria dos casos, mas não regra absoluta — é um JSON ou XML. O importante é que a API não guarda estado entre requisições (stateless): cada chamada contém tudo o que o servidor precisa, geralmente via headers, para processá-la.
Primeiros passos: fazer uma requisição GET
Vamos usar a PokéAPI, que é gratuita, sem token, e perfeita para testes. Ela retorna dados de Pokémon. O objetivo: buscar informações do Pikachu.
Python — com a lib requests
Instale: pip install requests
import requests
response = requests.get("https://pokeapi.co/api/v2/pokemon/pikachu")
print(f"Status code: {response.status_code}")
if response.status_code == 200:
data = response.json() # parseia JSON para dict do Python
print(f"Nome: {data['name']}")
print(f"Altura: {data['height']} decímetros")
print(f"Peso: {data['weight']} hectogramas")
else:
print("Erro ao buscar dados")
Repare que usei requests.get() e verifiquei o status_code. Um código 200 significa sucesso. Um 404 indica que o recurso não existe. Você vai ver isso o tempo todo.
JavaScript (Node.js 18+ com fetch nativo)
Sem instalar nada. O fetch já vem no ambiente.
// Executar com node arquivo.js
const url = "https://pokeapi.co/api/v2/pokemon/pikachu";
async function getPokemon(url) {
const resposta = await fetch(url);
console.log(`Status code: ${resposta.status}`);
if (resposta.ok) {
const dados = await resposta.json();
console.log(`Nome: ${dados.name}`);
console.log(`Altura: ${dados.height} decímetros`);
console.log(`Peso: ${dados.weight} hectogramas`);
} else {
console.log("Erro ao buscar dados");
}
}
getPokemon(url);
Java — com a classe HttpClient (Java 11+)
Sem dependência externa. O HttpClient é nativo.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ConsumirApi {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://pokeapi.co/api/v2/pokemon/pikachu"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status code: " + response.statusCode());
if (response.statusCode() == 200) {
String body = response.body();
// Imprimir só uma parte do JSON para exemplo
System.out.println(body.substring(0, 200));
} else {
System.out.println("Erro ao buscar dados");
}
}
}
Esses exemplos mostram a estrutura base de qualquer cliente HTTP. A partir daqui, você pode adaptar para qualquer API.
Enviando dados com POST e usando cabeçalhos
Muitas APIs exigem autenticação. O princípio: você envia um token no header Authorization. Vamos ver como fazer um POST genérico, simulando a criação de um recurso em uma API de teste (se preferir, use um localhost com um servidor simples tipo Flask).
Python — POST com header de autenticação
import requests
url = "https://api.exemplo.com/usuarios"
payload = {
"nome": "Ana",
"email": "ana@email.com"
}
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(f"Status code: {response.status_code}")
if response.status_code == 201: # 201 = Created, padrão REST para POST
print("Usuário criado com sucesso!")
print(response.json())
else:
print("Falha na requisição")
print(response.text)
JavaScript — POST com fetch e opções
const url = "https://api.exemplo.com/usuarios";
const payload = {
nome: "Ana",
email: "ana@email.com"
};
const opcoes = {
method: "POST", // Especifica a ação
headers: {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Content-Type": "application/json"
},
body: JSON.stringify(payload) // Transforma objeto em string JSON
};
async function criarUsuario() {
const resposta = await fetch(url, opcoes);
console.log(`Status code: ${resposta.status}`);
if (resposta.status === 201) {
const dados = await resposta.json();
console.log("Usuário criado:", dados);
} else {
console.log("Falha na requisição");
console.log(await resposta.text());
}
}
criarUsuario();
Java — POST com HttpRequest.BodyPublishers
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class PostExemplo {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = "{\"nome\": \"Ana\", \"email\": \"ana@email.com\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.exemplo.com/usuarios"))
.header("Authorization", "Bearer SEU_TOKEN_AQUI")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status code: " + response.statusCode());
System.out.println(response.body());
}
}
Lidando com erros e códigos HTTP de verdade
Você não vai escapar dos códigos HTTP. Tratá-los corretamente evita bugs silenciosos. Os mais comuns:
- 200 OK — sucesso no GET/UPDATE
- 201 Created — sucesso no POST
- 204 No Content — sucesso no DELETE (sem corpo de resposta)
- 400 Bad Request — você enviou dados inválidos. A culpa é do seu código.
- 401 Unauthorized — falta autenticação ou o token expirou
- 403 Forbidden — autenticado, mas sem permissão
- 404 Not Found — URL errada ou recurso não existe
- 429 Too Many Requests — você excedeu o limite de chamadas
- 500 Internal Server Error — o servidor quebrou. Não é você.
Tratar esses códigos é fazer seu programa não "explodir" silenciosamente. Por exemplo, em JavaScript:
const resposta = await fetch(url);
if (!resposta.ok) {
switch (resposta.status) {
case 401:
console.error("Credenciais inválidas. Revise o token.");
break;
case 404:
console.error("Recurso não encontrado. Verifique a URL.");
break;
case 429:
console.error("Muitas requisições. Aguarde 60 segundos.");
break;
default:
console.error(`Erro HTTP