O que é uma API REST e como funciona
Entenda o conceito de API REST, métodos HTTP, status codes e JSON antes de criar a sua.
O que é uma API?
API significa Application Programming Interface — Interface de Programação de Aplicações. É um conjunto de regras que permite que dois sistemas se comuniquem de forma padronizada, sem que um precise conhecer os detalhes internos do outro.
A analogia do garçom no restaurante
Imagine que você está em um restaurante. Você (o cliente) quer um prato específico, mas não vai até a cozinha prepará-lo. O garçom é o intermediário: você faz o pedido para ele, ele leva o pedido para a cozinha, a cozinha prepara e o garçom traz a resposta (o prato) de volta para você.
Nessa analogia:
- Você (cliente) = a aplicação que faz a requisição (frontend, app mobile, script Python)
- O garçom = a API, que recebe o pedido e devolve a resposta
- A cozinha = o servidor/banco de dados que processa a requisição
O garçom não precisa saber como o prato é preparado, e você não precisa saber o que acontece na cozinha. A API é exatamente essa camada de abstração.
O que significa REST?
REST (Representational State Transfer) é um estilo arquitetural criado por Roy Fielding em 2000. Não é um protocolo rígido — é um conjunto de princípios que, quando seguidos, tornam as APIs previsíveis, escaláveis e fáceis de consumir.
Princípios fundamentais do REST
| Princípio | O que significa |
|---|---|
| Cliente-Servidor | O cliente e o servidor são independentes. Cada um pode evoluir separadamente |
| Stateless | Cada requisição é independente. O servidor não guarda estado entre chamadas |
| Cacheable | Respostas podem ser cacheadas para melhorar performance |
| Interface uniforme | URLs consistentes, métodos HTTP padronizados, formato previsível |
| Sistema em camadas | O cliente não precisa saber se está falando com o servidor final ou um intermediário |
Na prática, uma API REST usa URLs para identificar recursos, métodos HTTP para definir ações e JSON para trocar dados.
Métodos HTTP
Os métodos HTTP definem qual ação será realizada sobre o recurso. Pense neles como verbos de uma frase: eles dizem o que você quer fazer.
| Método | Ação | Exemplo | Idempotente |
|---|---|---|---|
| GET | Buscar dados | Listar todos os usuários | Sim |
| POST | Criar recurso | Cadastrar um novo usuário | Não |
| PUT | Atualizar (completo) | Atualizar todos os campos do usuário | Sim |
| PATCH | Atualizar (parcial) | Atualizar apenas o email | Sim |
| DELETE | Remover recurso | Excluir um usuário | Sim |
Idempotente significa que fazer a mesma requisição várias vezes produz o mesmo resultado. Um GET sempre retorna os mesmos dados (se nada mudou). Um DELETE do mesmo recurso duas vezes resulta no mesmo estado final. Já um POST pode criar duplicatas se chamado duas vezes.
Exemplos de URLs REST bem projetadas
GET /api/tarefas → lista todas as tarefas
GET /api/tarefas/42 → busca a tarefa com id 42
POST /api/tarefas → cria uma nova tarefa
PUT /api/tarefas/42 → atualiza a tarefa 42 (todos os campos)
PATCH /api/tarefas/42 → atualiza parcialmente a tarefa 42
DELETE /api/tarefas/42 → remove a tarefa 42
Note que o recurso é sempre um substantivo no plural (tarefas, não getTarefas ou deletarTarefa). O método HTTP já indica a ação.
Status Codes HTTP
Toda resposta HTTP vem com um código de status numérico. Esses códigos informam ao cliente o que aconteceu com sua requisição.
Códigos de sucesso (2xx)
| Código | Nome | Quando usar |
|---|---|---|
| 200 | OK | Requisição bem-sucedida (GET, PUT, PATCH) |
| 201 | Created | Recurso criado com sucesso (POST) |
| 204 | No Content | Sucesso sem corpo na resposta (DELETE) |
Códigos de erro do cliente (4xx)
| Código | Nome | Quando usar |
|---|---|---|
| 400 | Bad Request | Dados inválidos enviados pelo cliente |
| 401 | Unauthorized | Autenticação necessária ou inválida |
| 403 | Forbidden | Autenticado, mas sem permissão |
| 404 | Not Found | Recurso não encontrado |
| 405 | Method Not Allowed | Método HTTP não suportado nessa rota |
| 409 | Conflict | Conflito (ex: email já cadastrado) |
| 422 | Unprocessable Entity | Dados válidos sintaticamente, mas inválidos semanticamente |
Códigos de erro do servidor (5xx)
| Código | Nome | Quando usar |
|---|---|---|
| 500 | Internal Server Error | Erro genérico no servidor |
| 502 | Bad Gateway | Servidor intermediário recebeu resposta inválida |
| 503 | Service Unavailable | Servidor temporariamente indisponível |
O formato JSON
JSON (JavaScript Object Notation) é o formato padrão para troca de dados em APIs REST modernas. Ele é leve, legível e suportado por praticamente todas as linguagens de programação.
{
"id": 1,
"nome": "Maria Silva",
"email": "maria@email.com",
"ativo": true,
"tags": ["python", "flask", "api"],
"endereco": {
"cidade": "Sao Paulo",
"estado": "SP"
}
}
Tipos de dados suportados pelo JSON
| Tipo | Exemplo |
|---|---|
| String | "texto aqui" |
| Number | 42, 3.14 |
| Boolean | true, false |
| Null | null |
| Array | [1, 2, 3] |
| Object | {"chave": "valor"} |
Em Python, a conversão é direta: dicionários viram objetos JSON, listas viram arrays, True/False viram true/false e None vira null.
O ciclo requisição-resposta
Toda comunicação com uma API REST segue o mesmo ciclo:
- O cliente monta a requisição: define a URL, o método HTTP, os headers e o corpo (se necessário)
- A requisição é enviada pela rede até o servidor
- O servidor processa: valida os dados, consulta o banco, aplica regras de negócio
- O servidor monta a resposta: define o status code, os headers e o corpo JSON
- A resposta é enviada de volta ao cliente
- O cliente processa a resposta: verifica o status code e usa os dados
Exemplo com Python
import requests
# 1. monta a requisicao
url = "https://api.github.com/users/python"
headers = {"Accept": "application/json"}
# 2. envia a requisicao
resposta = requests.get(url, headers=headers, timeout=10)
# 3-4. o servidor processou e respondeu
# 5-6. processa a resposta
print(resposta.status_code) # 200
print(resposta.headers["Content-Type"]) # application/json
dados = resposta.json()
print(dados["name"]) # Python
Headers HTTP
Headers são metadados enviados junto com a requisição ou resposta. Eles não fazem parte do corpo, mas carregam informações importantes sobre a comunicação.
Headers comuns em requisições
| Header | Para que serve | Exemplo |
|---|---|---|
Content-Type |
Formato do corpo enviado | application/json |
Accept |
Formato esperado na resposta | application/json |
Authorization |
Token de autenticação | Bearer eyJhbGci... |
User-Agent |
Identifica o cliente | MeuApp/1.0 |
Headers comuns em respostas
| Header | Para que serve | Exemplo |
|---|---|---|
Content-Type |
Formato do corpo retornado | application/json |
Content-Length |
Tamanho do corpo em bytes | 1234 |
Cache-Control |
Regras de cache | max-age=3600 |
X-RateLimit-Remaining |
Requisições restantes no limite | 58 |
Exemplos de APIs reais
API do GitHub
A API do GitHub é uma das mais bem documentadas e permite acessar repositórios, usuários, issues e muito mais.
import requests
# buscar informacoes de um repositorio
r = requests.get("https://api.github.com/repos/pallets/flask", timeout=10)
repo = r.json()
print(f"Nome: {repo['name']}")
print(f"Estrelas: {repo['stargazers_count']}")
print(f"Linguagem: {repo['language']}")
print(f"Descricao: {repo['description']}")
API de clima (wttr.in)
import requests
r = requests.get("https://wttr.in/Brasilia?format=j1", timeout=10)
dados = r.json()
atual = dados["current_condition"][0]
print(f"Temperatura: {atual['temp_C']} C")
print(f"Umidade: {atual['humidity']}%")
API de CEPs (ViaCEP)
import requests
r = requests.get("https://viacep.com.br/ws/01001000/json/", timeout=10)
endereco = r.json()
print(f"{endereco['logradouro']}, {endereco['bairro']}")
print(f"{endereco['localidade']} - {endereco['uf']}")
Ferramentas para testar APIs
Antes de escrever código, é útil testar as APIs usando ferramentas especializadas. Elas permitem enviar requisições, inspecionar respostas e depurar problemas rapidamente.
curl (linha de comando)
O curl vem instalado na maioria dos sistemas operacionais e é a forma mais rápida de testar uma API:
# requisicao GET simples
curl https://api.github.com/users/python
# com headers formatados
curl -s https://api.github.com/users/python | python -m json.tool
# requisicao POST com JSON
curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title": "Meu post", "body": "Conteudo", "userId": 1}'
# ver headers da resposta
curl -I https://api.github.com
HTTPie (linha de comando moderna)
O HTTPie é uma alternativa ao curl com saída colorida e sintaxe mais intuitiva:
# instalar
pip install httpie
# requisicao GET
http https://api.github.com/users/python
# requisicao POST
http POST https://jsonplaceholder.typicode.com/posts \
title="Meu post" body="Conteudo" userId:=1
# com autenticacao
http https://api.exemplo.com/dados Authorization:"Bearer meu_token"
Postman (interface gráfica)
O Postman é a ferramenta gráfica mais popular para testar APIs. Com ele você pode:
- Criar coleções de requisições organizadas por projeto
- Salvar variáveis de ambiente (tokens, URLs base)
- Gerar documentação automática
- Compartilhar coleções com o time
- Criar testes automatizados para cada endpoint
É gratuito para uso individual e pode ser baixado em postman.com.
Resumo
| Conceito | Descrição |
|---|---|
| API | Interface que permite comunicação entre sistemas |
| REST | Estilo arquitetural baseado em recursos e métodos HTTP |
| Método HTTP | Verbo que define a ação (GET, POST, PUT, DELETE) |
| Status Code | Código numérico que indica o resultado da requisição |
| JSON | Formato padrão para troca de dados em APIs |
| Header | Metadados enviados junto com requisição/resposta |
| Endpoint | URL que identifica um recurso na API |
Agora que você entende os fundamentos, no próximo artigo vamos colocar a mão no código e criar uma API REST completa com Flask.