Alguns conceitos sobre API’s que devias conhecer
É só enviar um POST para o endpoint com os headers e payload corretos…
A sério? Se é realmente isso que pensas precisas de ler isto.
Se já concordaste com a cabeça numa reunião enquanto pesquisavas no Google o que significa “rate limiting” ou “parâmetros query”, relaxa que não estás sozinho. Todos já passamos por isso.
Na realidade as API’s estão em todo lado. O tua app favorita? Usa uma API. O app que usaste pra pedir comida ou para chamar uma boleia? Usa uma API. Quando o calendário é atualizado automaticamente depois de receberes e aceitares um invite? Sim, também é uma API.
Então vamos simplificar isto tudo para percebermos todos os conceitos à volta de uma API.
A seguir vou enumerar alguns pontos importantes sobre API’s usando algumas analogias do dia a dia.
📦 Recurso (Resource)
Quando falamos de REST API’s, um dos conceitos mais importantes é o recurso — ou em inglês, resource. Compreender bem o que é um recurso, é meio caminho para dominar a arquitetura REST.
🎯 O que é um Recurso?
Um recurso é uma qualquer entidade com a qual queiramos interagir através da API.
Pode ser algo tangível como um produto, utilizador, imagem, ou algo mais abstrato como uma sessão, comentário ou autenticação.
👉 Pensa num recurso como um objeto do mundo real ou digital que pode ser representado por dados.
Exemplos de recursos:
- Um utilizador (
/users/42
) - Um artigo de blog (
/posts/88
) - Uma imagem (
/images/1023
) - Um evento no calendário (
/events/2025-05-04
)
🌐 Recursos são acedidos através de um URL
No REST, cada recurso tem um identificador único — geralmente um endpoint ou URL.
Por exemplo:
GET /users
→ Lista de utilizadoresGET /users/42
→ Detalhes do utilizador com ID 42PUT /users/42
→ Atualizar o utilizador 42DELETE /users/42
→ Remover o utilizador 42
Estás a ver a lógica? Trabalhamos sempre sobre “coisas” — os recursos.
📚 Um recurso tem representação
O que recebemos (ou enviamos) ao interagir com um recurso é a representação dele.
Normalmente, esta representação é em JSON (mas pode ser XML, HTML, etc.).
Exemplo de representação de um recurso user
:
{
"id": 42,
"name": "Ana Silva",
"email": "ana@example.com"
}
🔁 Recursos e métodos HTTP
Em REST, usamos os verbos HTTP para operar sobre os recursos:
- GET para ler
- POST para criar
- PUT para atualizar
- DELETE para remover
🧠 Regra de ouro
“Em REST, anda tudo á volta de recursos.”
Se estás a desenhar uma API, pensa sempre:
Qual é o recurso? Qual a sua representação? E que ações posso fazer sobre ele?
💡 Dica para quem está a arquitetar uma API REST
Modela os recursos com nomes no plural e sem verbos.
Porquê? Porque o verbo já está no método HTTP.
Por exemplo:
- ✅
GET /users
- ❌
GET /getUserList
REST não é sobre ações, é sobre coisas.
📩 Pedido (Request): Como tudo começa numa API
Se o recurso é o “quê”, o pedido (ou request) é o “como”.
De uma forma simples, um pedido é a forma como um cliente (uma app ou um browser) pede algo ao servidor.
🗣️ O que é um Pedido?
Um request é uma mensagem enviada por um cliente a uma API a dizer:
“Quero fazer algo com este recurso.”
É como quando entras num restaurante e fazes o teu pedido ao empregado.
Tu és o cliente, a API é o empregado, e o que pedes é o request.
⚙️ Componentes do Pedido
Um pedido típico tem várias partes importantes:
🔸 1. Método (HTTP Verb)
Define a ação que queremos fazer com o recurso.
GET
→ Obter dadosPOST
→ Criar algo novoPUT
→ Atualizar algo existenteDELETE
→ Apagar
🔸 2. URL (Endpoint)
Diz qual o recurso que queremos aceder ou modificar.
Exemplo:
GET /users/42
Aqui estamos a pedir os dados do utilizador com ID 42.
🔸 3. Headers
Metadados do pedido — como se fossem etiquetas com instruções.
Authorization: Bearer <token>
Content-Type: application/json
- Informam o tipo de conteúdo enviado
- Transportam tokens de autenticação
- Indicam preferências do cliente (idioma, formato, etc.)
🔸 4. Body (Corpo do pedido)
Só existe em em métodos como o POST
ou o PUT
. É aqui que vai o payload (dados a enviar).
Exemplo:
{
"name": "João",
"email": "joao@example.com"
}
🛠️ Exemplo completo de um Pedido
POST /users HTTP/1.1
Host: api.exemplo.com
Authorization: Bearer abc123
Content-Type: application/json
{
"name": "João",
"email": "joao@example.com"
}
Neste exemplo, estamos a:
- Usar o método
POST
para criar um novo utilizador - Enviar os dados no corpo do pedido (em JSON)
- Incluir um token no header para autenticação
🤝 Client → API
O pedido é sempre iniciado do lado do cliente (app mobile, frontend web, scripts, etc.).
A API é o servidor, que vai receber o pedido, processá-lo, e devolver uma resposta.
🔁 Pedido e resposta
“Todos os pedidos esperam uma resposta.”
Depois de enviar um pedido, recebemos uma resposta — e é aqui vai entrar o próximo conceito.
📬 Resposta (Response): A resposta da API ao teu pedido
Se o request é o teu pedido ao restaurante, a response (ou resposta) é o prato que o empregado traz à tua mesa — seja ele delicioso ou… um aviso de que está esgotado.
Nas API’s, todos os pedidos recebem uma resposta. Sempre. Mesmo que seja só para dizer:
“não encontrei nada”.
🧾 O que é uma resposta?
Uma resposta é a mensagem enviada de volta pela API com o resultado do pedido feito pelo cliente.
É o “sim”, “não” ou “houve um problema” do servidor, muitas vezes acompanhado por dados.
⚙️ Componentes de uma Resposta
Uma resposta tem vários elementos importantes que ajudam o cliente a compreender o que aconteceu com o seu pedido:
🔸 1. Código de Estado (Status Code)
O código HTTP que resume o resultado da operação.
Exemplos:
200 OK
– Tudo certo!201 Created
– Recurso criado com sucesso400 Bad Request
– Erro no pedido404 Not Found
– O recurso não existe500 Internal Server Error
– Algo correu mal no servidor
👉 Estes códigos são padronizados e ajudam o cliente a reagir corretamente.
🔸 2. Headers
Tal como no pedido, a resposta também contém metadados: tipo de conteúdo, políticas de cache, encoding, etc.
Exemplo:
Content-Type: application/json
Cache-Control: no-cache
🔸 3. Corpo (Body)
É aqui que vem o conteúdo da resposta — muitas vezes em JSON, com os dados pedidos ou detalhes sobre o erro.
Exemplo:
{
"id": 42,
"name": "João",
"email": "joao@example.com"
}
📦 Exemplo completo de uma Resposta
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 42,
"name": "João",
"email": "joao@example.com"
}
Esta resposta mostra que:
- O pedido foi bem-sucedido (
200 OK
) - O conteúdo está em formato JSON
- E estamos a receber os dados do utilizador com ID 42
📉 Nem sempre vem com sucesso
Nem todas as respostas trazem boas notícias.
Às vezes recebemos um erro, e isso também é uma resposta válida:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "Utilizador não encontrado"
}
O importante é que, mesmo em caso de falha, a API comunique de forma clara e padronizada o que aconteceu.
🔁 Request e Response: o ciclo básico de uma API
“Cada pedido espera uma resposta — e o par define o ciclo fundamental da comunicação entre cliente e servidor.”
Saber interpretar uma resposta ajuda-te a:
- Diagnosticar problemas
- Reagir corretamente no teu código
- Criar UIs mais inteligentes e responsivos
🧾 Códigos de Resposta: A linguagem do servidor
Sempre que fazes um pedido a uma API, ela responde com um código de estado HTTP.
Este código é como se fosse um sinal de trânsito: diz-te se podes avançar, se tens de parar ou se algo correu mal.
📊 O que são os Códigos de Resposta?
Os códigos de resposta HTTP são números de 3 dígitos que indicam o resultado do teu pedido.
São padronizados pela internet (RFC 7231) e permitem que aplicações saibam como reagir sem sequer ter de olhar para o conteúdo da resposta.
📚 As 5 classes de códigos
Os códigos são agrupados por classes conforme o primeiro dígito:
🟦 1xx — Informativo
“Recebi o pedido. Estou a processar.”
Estes códigos indicam que o pedido foi recebido e está a ser processado. São raramente usados diretamente em API’s públicas.
🔸 100 Continue — O servidor recebeu os headers e aguarda o corpo do pedido.
✅ 2xx — Sucesso
“Tudo certo. A operação foi concluída com sucesso.”
Aqui está o que queremos ver sempre! A ação foi executada sem problemas.
- 200 OK — Resposta por defeito para sucesso.
- 201 Created — Foi criado um novo recurso com sucesso.
- 204 No Content — Sucesso, mas sem dados a enviar.
🔁 3xx — Redirecionamento
“O recurso está noutro sitio. Segue este novo caminho.”
Usado quando é necessário redirecionar o cliente para outro URL ou recurso.
- 301 Moved Permanently — O recurso mudou de endereço (definitivamente).
- 302 Found — Redirecionamento temporário.
- 304 Not Modified — Nada mudou desde o último pedido (útil quando usamos cache).
⚠️ 4xx — Erro do Cliente
“Oops… o teu pedido está errado.”
Estes códigos indicam que algo falhou no pedido enviado pelo cliente (ex: erro de sintaxe, falta de permissões, etc).
- 400 Bad Request — Pedido mal formado.
- 401 Unauthorized — Não autenticado (login/token em falta ou inválido).
- 403 Forbidden — Acesso proibido, mesmo quando autenticado.
- 404 Not Found — O recurso não foi encontrado.
- 429 Too Many Requests — Excesso de pedidos (o limite de pedidos foi atingido).
🔴 5xx — Erro do Servidor
“A culpa é nossa. Tivemos um problema do lado do servidor.”
Estes códigos indicam que o pedido até pode estar certo, mas algo correu mal no servidor.
- 500 Internal Server Error — Erro genérico do servidor.
- 502 Bad Gateway — O servidor recebeu uma resposta inválida de outro sitio.
- 503 Service Unavailable — Servidor indisponível (sobrecarga, manutenção, etc.).
- 504 Gateway Timeout — Timeout ao aguardar resposta de outro serviço.
Podes consultar todos os códigos de resposta aqui.
🧠 Boas práticas ao usar códigos de resposta
- Escolhe o código certo para cada tipo de operação
- Evita sempre o 500 genérico — envia erros claros e previsíveis
- Usa o 204 No Content quando a resposta não tem corpo
- Usa
422
em vez de400
quando queres indicar uma falha de validação com mais detalhe
🧪 Exemplo prático: API de utilizadores
Pedido:
POST /users
Content-Type: application/json
{
"name": "João"
}
Resposta:
HTTP/1.1 201 Created
Location: /users/123
Content-Type: application/json
{
"id": 123,
"name": "João"
}
O servidor respondeu com:
201 Created
: novo recurso criado- Cabeçalho
Location
: onde está o novo recurso - Corpo com a representação do novo utilizador
📦 Payload: O conteúdo da tua mensagem
Se o pedido é o envelope, o payload é a carta lá dentro.
É a informação que estás a enviar ou a receber numa comunicação com uma API.
🧾 O que é o Payload?
O payload é o conteúdo útil transportado num pedido ou numa resposta.
É o que realmente interessa— os dados que queremos enviar para o servidor ou obter na resposta.
Em API’s REST, o payload geralmente está no corpo (body) da mensagem, em formato JSON.
📨 Payload no Pedido
Quando envias dados para criar ou atualizar alguma coisa, o payload vai no corpo do pedido.
Exemplo com POST
(criação):
POST /users
Content-Type: application/json
{
"name": "Joana",
"email": "joana@example.com"
}
Neste caso:
- O payload são os dados do novo utilizador
- A API vai usá-los para criar um novo recurso no servidor
📤 Payload na Resposta
Ao fazer um GET
, o servidor devolve dados — esse também é o payload, mas neste caso, na resposta:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 101,
"name": "Joana",
"email": "joana@example.com"
}
Aqui, o payload é o objeto JSON com os dados do utilizador.
A tua aplicação pode usar esta informação para o que necessitar. Mostrar no ecrã, guardar localmente, etc.
🛠️ Outros exemplos de payload
- Enviar ficheiros (ex: imagem de perfil) via
multipart/form-data
- Enviar arrays de objetos para importações em massa
- Receber listas paginadas de dados
🔒 Considerações importantes
- O formato do payload deve estar de acordo com o que a API espera (
application/json
,form-data
, etc.) - O payload deve ser válido e bem estruturado — caso contrário, a API pode responder com erro um
400
ou422
- API’s modernas validam e respondem com mensagens claras em caso de problemas no payload
❌ O que não é payload?
Nem tudo no pedido ou resposta é payload:
- ❌ Headers: Metadados (ex: tipo de conteúdo, auth)
- ❌ URL/Query: Identificação ou filtragem de recursos
- ✅ Body (JSON): Sim, é o payload (conteúdo útil)
🧠 Em resumo
- Payload = os dados que realmente interessam (úteis para o negócio)
- Pode ir no pedido (quando enviamos dados) ou na resposta (quando recebemos dados)
- Normalmente em JSON, mas pode ser texto, XML, ficheiros, etc.
📚 Paginação: A dividir para conquistar
Já tentaste carregar todos os comentários de um vídeo do YouTube de uma vez? Ou abrir uma lista com 10.000 utilizadores de uma aplicação?
Seria lento, pesado e pouco eficiente.
É aqui que entra a paginação — uma técnica para dividir dados em partes mais pequenas, tornando tudo mais rápido, mais leve e mais controlável.
📦 O que é paginação?
Paginação é a prática de segmentar os resultados de uma API em “páginas”.
Em vez de devolver tudo de uma vez, a API envia um conjunto limitado de items por resposta, e permite navegar entre páginas.
📈 Porquê usar?
- Melhora performance
- Reduz uso de memória no cliente e no servidor
- Permite uma melhor UX (usando carregamento progressivo de dados)
- Evita timeouts e erros 500 em listas muito grandes
🔧 Como funciona?
A API geralmente recebe parâmetros query para controlar a paginação:
🔹 Exemplo comum com limit
e offset
:
GET /users?limit=10&offset=20
limit=10
: queremos 10 resultados por páginaoffset=20
: queremos começar no item 21
Neste caso, estaríamos a pedir a “3ª página” de resultados.
🔹 Outra abordagem: page
e per_page
GET /products?page=2&per_page=25
page=2
: queremos a página 2per_page=25
: queremos ter 25 registos por página
Neste caso, estaríamos a pedir a “2ª página” de resultados, que iria começar no registo 26.
📬 Resposta paginada típica
{
"data": [
{ "id": 26, "name": "Produto A" },
{ "id": 27, "name": "Produto B" }
],
"pagination": {
"page": 2,
"per_page": 2,
"total_pages": 10,
"total_items": 20
}
}
🔍 Estes metadados ajudam o cliente a:
- Saber quantas páginas existem
- Mostrar botões de “Próxima” e “Anterior”
- Decidir se deve continuar a carregar dados
🛠️ Outras técnicas de paginação
✅ Cursor-based pagination (mais avançado)
Em vez de offset, usa um “cursor” que aponta para o próximo conjunto:
GET /posts?after=abc123&limit=10
Mais eficiente em grandes bases de dados ou aplicações em tempo real, pois evita problemas com dados que mudam entre pedidos.
🔒 Boas práticas
- Define um
limit
máximo para evitar abuso - Usa paginação sempre que uma coleção pode crescer muito
- Inclui metadados de paginação na resposta (ex: total de items, página atual, etc.)
- Testa se a paginação funciona bem com filtros e ordenações
🧠 Em resumo
- Paginação = segmentar dados em partes “geríveis”
- Melhora performance, usabilidade e robustez da API
- Existem várias abordagens:
offset
,page
,cursor
… - É essencial quando trabalhas com coleções grandes
🔨 HTTP Methods: Os verbos da API
Se os recursos são os substantivos numa API (ex: utilizadores, produtos, posts), os métodos são os verbos.
São eles que indicam a ação que queremos realizar:
Ler, criar, atualizar, apagar — tudo começa com um método
🧾 O que são métodos HTTP?
São comandos padronizados do protocolo HTTP que indicam a intenção do pedido.
Numa API RESTful, os métodos mais comuns são:
GET
Obter dados — ReadPOST
Criar novos dados — CreatePUT
Atualizar dados — UpdatePATCH
Atualizar parcialmente — Update (parcial)DELETE
Apagar dados — Delete
📘 GET
– Obter dados
Usado para consultar informações. Não altera nada no servidor.
GET /users/123
Pede os dados do utilizador com ID 123.
- Deve ser seguro e idempotente (repetir o pedido não muda o resultado)
- O payload vai na resposta, não no pedido
📝 POST
– Criar algo novo
Usado para criar um novo recurso. Envia-se um payload com os dados.
POST /users
Content-Type: application/json
{
"name": "Carlos",
"email": "carlos@example.com"
}
- Normalmente devolve
201 Created
- Pode incluir o header
Location
com o URL do novo recurso
🛠️ PUT
– Substituir um recurso
Usado para atualizar (ou substituir) completamente um recurso existente.
PUT /users/123
Content-Type: application/json
{
"name": "Carlos Atualizado",
"email": "carlos@novo.com"
}
- Se o recurso não existir, pode criar (conforme a implementação)
- Substitui todo o objeto
🧩 PATCH
– Atualizar parcialmente
Usado para alterar só uma parte de um recurso, sem ser necessário enviar tudo.
PATCH /users/123
Content-Type: application/json
{
"email": "novo@email.com"
}
- Mais leve que
PUT
- Ideal para edições pequenas
❌ DELETE
– Remover um recurso
Usado para apagar um recurso.
DELETE /users/123
- Se tudo correr bem, devolve
204 No Content
- Deve ser idempotente (apagar duas vezes não dá erro)
🔒 Métodos + segurança
Alguns métodos necessitam autenticação e autorização, especialmente:
POST
,PUT
,PATCH
,DELETE
→ porque alteram o estado dos dados- API’s devem validar permissões antes de executar qualquer ação
🧠 Em resumo
- Os métodos HTTP expressam intenção: obter, criar, atualizar, apagar
- Seguem o modelo CRUD (Create, Read, Update and Delete)
- Devem ser bem aplicados para manter uma API RESTful, previsível e limpa
🔍 Query Parameters: A pedir com jeitinho
Imagina que entras numa loja e dizes:
“Quero sapatos.”
Mas se fores mais específico:
“Quero sapatos pretos, tamanho 42, em promoção.”
É disso que tratam os query parameters — pequenos detalhes que enviamos no URL para refinar aquilo que estamos a pedir.
🧾 O que são query parameters?
São pares chave-valor incluídos no final do URL de um pedido, normalmente em métodos GET
.
Permitem filtrar, ordenar, limitar ou personalizar os dados devolvidos pela API.
A estrutura é sempre:
?chave1=valor1&chave2=valor2
🔹 Exemplo simples
GET /produtos?categoria=livros&preco_max=20
- Estamos a pedir produtos da categoria “livros” com preço até 20€
- Os parâmetros
categoria
epreco_max
são query parameters
📦 Onde aparecem?
Sempre na URL — depois de um ?
, separados por &
:
GET /users?age=30&country=pt
⚙️ Usos típicos
- Filtros
/users?role=admin
- Paginação
/posts?page=3&limit=10
- Ordenação
/products?sort=price_asc
- Pesquisa
/articles?q=javascript
- Campos específicos
/users?fields=name,email
- Relações
/orders?include=products
🧠 Boas práticas
- Dá nomes claros e consistentes aos parâmetros
- Usa tipos adequados:
boolean
,number
,string
, etc. - Documenta todos os parâmetros suportados pela API
- Permite combinações de parâmetros (ex: filtros + ordenação + paginação)
⚠️ Cuidado com…
- URLs demasiado longas (limites no browser/servidor)
- Dados sensíveis nos query parameters (visíveis no histórico e logs)
- Ambiguidade — evita nomes genéricos ou com múltiplos significados
🧠 Em resumo
- Query parameters são opcionais mas muito úteis
- Tornam os pedidos mais ricos, precisos e controlados
- Devem ser tratados no servidor para devolver resultados relevantes e rápidos
🔐 Autenticação: Quem és tu?
Imagina que estás à porta de um edifício com segurança.
Antes de entrares, tens de mostrar um cartão, um código ou a tua identidade.
Com uma API, é igual:
A autenticação garante que a aplicação sabe quem está a fazer o pedido.
🧾 O que é Autenticação?
É o processo de verificar a identidade de quem faz o pedido.
A API precisa de saber se pode confiar em ti (ou na tua aplicação).
Sem autenticação, qualquer pessoa podia:
- Ver dados privados
- Criar spam
- Alterar ou apagar recursos sensíveis
👤 Quem precisa de se autenticar?
- Utilizadores (ex: ao usar uma aplicação com login)
- Aplicações (ex: um sistema externo que consome a tua API)
- Dispositivos (ex: IoT, mobile apps, etc.)
🛠️ Como funciona na prática?
Normalmente, enviamos algo que nos identifique (ex. um token, uma api key, ou credenciais) juntamente com o com o pedido.
A API verifica se a identidade é válidaantes de devolver os dados.
🔑 Tipos comuns de autenticação:
1. API Key (chave de API)
Um identificador simples enviado no cabeçalho ou URL.
GET /dados
Authorization: Api-Key 12345abcde
ou
GET /dados?apiKey = 12345abcde
- Fácil de usar
- Boa para sistemas entre aplicações
- Pouco segura se não for usada com HTTPS
2. Basic Auth
Envia o utilizador e palavra-passe codificados em base64.
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
- Simples, mas pouco seguro
- Deve sempre ser usado com HTTPS
- Pouco recomendada para API’s modernas
3. Bearer Token (JWT, OAuth, etc.)
Token seguro que representa o utilizador autenticado.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR...
- Comum em API’s modernas
- Pode incluir informação no próprio token (JWT)
- Usado em conjunto com login, OAuth, etc.
4. OAuth 2.0
Padrão moderno e robusto, ideal para autenticação entre sistemas e terceiros.
Exemplo: Usar o login do Google para entrar numa aplicação externa.
- Baseado em tokens temporários
- Permite granularidade (ex: “lê só os contactos, não os e-mails”)
- Mais complexo de implementar
📵 O que acontece sem autenticação?
Se tentares aceder a um endpoint protegido sem te identificares, a API responde:
401 Unauthorized
Se te identificares mas não tiveres permissão, então responde:
403 Forbidden
🧠 Em resumo
- A autenticação protege os dados e a aplicação
- Existem várias estratégias, desde simples API Keys até estratégias mais robustas como OAuth
- A escolha depende do nível de segurança, escalabilidade e facilidade de implementação
🚦 Rate Limiting: Calma aí, campeão!
As API’s são como cafés movimentados. Há um limite de quantas pessoas podem ser atendidas ao mesmo tempo.
Se todos fizerem pedidos ao mesmo tempo, o sistema entra em colapso.
É aqui que entra o Rate Limiting:
Um mecanismo que limita quantos pedidos um cliente pode fazer num determinado período de tempo.
🧾 O que é Rate Limiting?
É a prática de restringir o número de pedidos permitidos a uma API por:
- Utilizador
- IP
- Aplicação
- Token
- …
…dentro de uma janela temporal.
🧮 Exemplos comuns
- 1000 pedidos por hora — Cada cliente pode fazer até 1000 pedidos/h
- 10 pedidos por segundo — Proteção contra sobrecarga instantânea
- 60 logins por minuto — Prevenção de brute force
🔐 Por que existe?
- Evitar abuso ou ataques (DoS / brute force)
- Garantir estabilidade do sistema
- Distribuir recursos de forma justa entre utilizadores
- Proteger serviços downstream (ex: base de dados, sistemas terceiros)
📦 Como é implementado?
Normalmente com cabeçalhos HTTP que avisam o cliente dos seus limites.
Exemplo de resposta com rate limit:
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 998
X-RateLimit-Reset: 1714837200
X-RateLimit-Limit
: Total de pedidos permitidosX-RateLimit-Remaining
: Quantos ainda podes fazerX-RateLimit-Reset
: Quando o contador reinicia (timestamp)
❌ Excedeste o limite?
Se fizeres mais pedidos do que deves, a API responde com:
429 Too Many Requests
E muitas vezes inclui uma mensagem do tipo:
{
"error": "Rate limit exceeded. Try again in 15 seconds."
}
🧠 Boas práticas (para clientes)
- Lê os cabeçalhos para saber os teus limites
- Usa backoff exponencial (esperar mais a cada tentativa falhada)
- Evita loops que disparem pedidos em massa
- Implementa cache local sempre que possível
🧠 Boas práticas (para quem constrói a API)
- Define limites razoáveis, por tipo de utilizador (ex: gratuito vs pago)
- Informa claramente os limites na documentação
- Inclui os cabeçalhos com os dados de rate limit
- Usa tecnologias com suporte nativo, como NGINX, API Gateway, etc.
💡 Em resumo
- Rate limiting é o “bouncer” da tua API
- Garante desempenho, segurança e estabilidade
- Ajuda-te a escalar a API de forma sustentável
🤝 API Integration: Quando aplicações se tornam melhores amigas
Pensa em duas aplicações que falam uma com a outra.
Um evento no Google Calendar que aparece automaticamente no Slack?
Uma loja online que mostra stocks atualizados em tempo real a partir do armazém?
Uma aplicação de delivery que te avisa quando a comida sai do restaurante?
Tudo isto é possível graças às integrações entre APIs.
🧾 O que é uma integração com API?
É o processo de ligar diferentes sistemas entre si, permitindo que:
- Troquem informações
- Disparem ações automaticamente
- Trabalhem juntos como um só
A integração transforma APIs solitárias em colaboradoras em rede
🔗 Exemplos do mundo real
- Slack + Google Calendar — Recebes alertas de eventos diretamente no Slack
- Loja online + Sistema de stock — Atualização automática de disponibilidade
- Trello + Gmail — Criar tarefas a partir de e-mails
- CRM + ERP — Sincronização de clientes e faturação
⚙️ Como funciona na prática?
Normalmente, uma aplicação faz pedidos a outra API em momentos chave.
Exemplo:
Quando adicionas um novo utilizador no sistema A, ele é automaticamente criado no sistema B:
POST /api/users
{
"name": "Joana",
"email": "joana@example.com"
}
Isto pode acontecer:
- Manualmente (ex: botão “sincronizar”)
- Automaticamente (ex: via webhook ou cron job)
🧠 Benefícios das integrações
- Automação de tarefas repetitivas
- Eficiência operacional
- Redução de erros manuais
- Melhor experiência de utilizador
- Maior escala e velocidade de negócio
📦 Tipos de integração
- One-way — Uma app envia dados à outra (ex: notificações)
- Two-way (bidirecional) — Ambas enviam e recebem dados (ex: sincronização de dados)
- Síncrona — Uma app espera resposta imediata
- Assíncrona — Os dados chegam depois, via callback ou webhook
🛠️ Ferramentas comuns
- APIs REST (HTTP + JSON)
- Webhooks (eventos push)
- Middleware de integração (ex: Zapier, Make)
- Sistemas de mensagens (Kafka, RabbitMQ, etc.)
📌 Coisas a considerar
- Autenticação entre sistemas (OAuth, API Keys)
- Segurança e controlo de acesso
- Tolerância a falhas (e reenvios)
- Limites de rate (não sobrecarregar APIs externas)
- Versionamento de APIs
💡 Em resumo
- Integrações com API ligam aplicações distintas para trabalharem em conjunto
- Permitem automação, sincronização e melhorias na experiência
- São cada vez mais essenciais no desenvolvimento moderno de software (ex: arquiteturas de micro-serviços)
🧰 API Gateway: O porteiro (e guarda-costas) da tua API
Imagina que tens várias APIs espalhadas pelos bastidores da tua aplicação:
- Uma para gerir utilizadores
- Outra para processar pagamentos
- Outra para enviar notificações
Agora pensa num ponto único de entrada que:
- Recebe todos os pedidos
- Valida, transforma e encaminha cada um
- Aplica regras de segurança
- Esconde os detalhes internos da aplicação
Isso é o API Gateway: o intermediário inteligente entre os clientes e os serviços da tua arquitetura.
🧾 O que é um API Gateway?
É uma camada de abstração que:
- Centraliza todos os pedidos feitos à tua aplicação
- Encaminha os pedidos para os serviços corretos
- Aplica funcionalidades como autenticação, rate limiting, logs, transformação de dados e muito mais
🎯 O que faz?
- Roteamento de pedidos — Direciona o pedido ao microserviço correto
- Autenticação e segurança — Verifica tokens, permissões, etc.
- Rate Limiting — Aplica limites de acesso para evitar abusos
- Caching — Guarda respostas temporárias para acelerar pedidos frequentes
- Transformação de dados — Altera headers, formatos ou estruturas de dados entre cliente e serviço
- Monitorização e logs — Recolhe métricas, regista acessos e erros
- Agregação de respostas — Junta respostas de múltiplos serviços num único resultado
🧱 Onde é usado?
Muito comum em arquiteturas de microserviços, onde:
- Há muitos serviços independentes
- Precisas de um ponto único de entrada (como numa API pública)
- Queres evitar expor diretamente os serviços internos
🛡️ Exemplo prático
[Cliente] → [API Gateway] → [Serviço de Utilizadores]
↘→ [Serviço de Pagamentos]
↘→ [Serviço de Notificações]
O cliente só conhece o API Gateway. Ele não sabe (nem precisa de saber) como os serviços internos funcionam.
🚀 Benefícios
- Centralização da lógica transversal (segurança, logs, limites)
- Simplificação dos clientes (um unico ponto de acesso)
- Facilidade de escalar e versionar os serviços por trás
- Mais controlo e visibilidade sobre o tráfego
🧠 Exemplos de API Gateways populares
- Kong
- AWS API Gateway
- Apigee (Google)
- Azure API Management
- Nginx (com configurações específicas)
- Traefik
📌 Cuidados a ter
- Pode tornar-se um ponto único de falha (usa balanceamento e alta disponibilidade)
- Aumenta ligeiramente a latência
- Requer configuração e monitorização cuidadosa
💡 Em resumo
- O API Gateway é o porteiro central da tua infraestrutura
- Controla, protege e encaminha pedidos com inteligência
- É essencial para arquiteturas modernas, especialmente em microserviços
🔄 API Lifecycle: Da criação ao fim de vida
Tal como qualquer produto digital, uma API não é estática.
Ela tem um ciclo de vida — um percurso que começa na ideia e termina (às vezes) na desativação.
Gerir este ciclo com cuidado é fundamental para manter a tua API útil, segura e relevante ao longo do tempo.
🧾 Etapas principais do ciclo de vida de uma API
1. Planeamento (Design)
Tudo começa com perguntas:
- Que problema a API resolve?
- Quem são os utilizadores?
- Quais os recursos disponíveis?
- Que métodos vamos disponibilizar?
💡 Aqui definem-se os endpoints, os formatos de dados, os métodos HTTP, o modelo de autenticação, etc.
2. Desenvolvimento
Agora é hora de pôr as mãos no código:
- Implementar os endpoints
- Aplicar validações, autenticação, logging, etc.
- Escrever testes unitários e de integração
📦 Muitas vezes usa-se OpenAPI (Swagger) para documentar.
3. Testes
Testes automáticos e manuais garantem que a API:
- Funciona como esperado
- É segura contra abusos
- Aguenta carga (teste de performance)
4. Publicação e disponibilização
A API é lançada e publicada:
- Disponibilização de documentação
- Entrega de chaves de API aos clientes
- Criação de ambientes (dev, staging, prod)
🌍 Pode ser interna, pública ou partilhada com parceiros.
5. Monitorização e gestão
Uma vez em produção, a API precisa de:
- Logs e métricas (uso, erros, latência)
- Alertas automáticos
- Atualizações de segurança
🛠️ Ferramentas como API Gateway, Prometheus, Grafana ou Datadog são comuns nesta fase.
6. Versionamento e evolução
Com o tempo, surgem novas necessidades:
- Novos endpoints
- Mudanças de formato
- Melhoria de performance
🚧 Para evitar partir clientes existentes, é comum usar versionamento:
/v1/users
/v2/users
7. Depreciação e fim de vida
Eventualmente, algumas versões tornam-se obsoletas.
O ciclo encerra-se com:
- Avisos de descontinuação
- Prazo para migração
- Desativação da API antiga
🧼 Isto garante que o ecossistema se mantém saudável, moderno e seguro.
📌 Dica de ouro
Tratar uma API como um produto — com planeamento, feedback e evolução constante — é a melhor forma de garantir o seu sucesso.
💡 Em resumo
- O ciclo de vida da API vai muito além do código
- Cada fase (do design ao fim) tem impacto na experiência do utilizador
- Gerir bem o ciclo = menor dor de cabeça e mais valor a longo prazo
✍️ CRUD: As 4 operações básicas de uma API
CRUD é um acrónimo para:
- Create (Criar)
- Read (Ler)
- Update (Atualizar)
- Delete (Apagar)
Estas quatro operações representam o ciclo de vida completo de qualquer dado dentro de uma aplicação. Se uma API lida com dados (e quase todas lidam), ela provavelmente implementa operações CRUD.
📦 Mapeamento com métodos HTTP
Cada operação CRUD tem um método HTTP correspondente:
- Create
POST
— Cria um novo utilizador
POST /users - Read
GET
— Lê os dados do utilizador 123
GET /users/123 - Update
PUT
/PATCH
— Atualiza os dados do utilizador 123
PUT /users/123 - Delete
DELETE
— Apaga o utilizador 123
DELETE /users/123
🔄 Diferença entre PUT e PATCH
PUT
→ Atualização completa (substitui o recurso todo)PATCH
→ Atualização parcial (muda só o que for indicado)
👀 Exemplo prático com um recurso Livro
POST /livros
{
"titulo": "Clean Code",
"autor": "Robert C. Martin"
}
➡️ Cria um novo livro
GET /livros/10
➡️ Lê os dados do livro com ID 10
PUT /livros/10
{
"titulo": "Clean Code",
"autor": "Uncle Bob"
}
➡️ Atualiza completamente o livro 10
DELETE /livros/10
➡️ Apaga o livro 10
🧠 Porque é importante compreender o CRUD?
- É a base da persistência de dados
- Serve como guia para estruturar API’s REST
- Ajuda a manter uma interface coerente e previsível para os consumidores da API
💡 Em resumo
- CRUD define as 4 operações fundamentais com dados
- Cada uma tem uma correspondência clara no mundo HTTP
- Saber isto ajuda-te a usar e desenhar API’s de forma intuitiva
⚡ Cache: Guarda o que é frequente, responde mais depressa
Imagina que perguntas constantemente à mesma API:
“Qual é a temperatura em Lisboa agora?”
Se a resposta for igual durante vários minutos, não faz sentido repetir todo o processamento do lado do servidor. Em vez disso, a resposta pode ser guardada em cache — e servida diretamente da memória ou de um armazenamento temporário.
🧾 O que é cache?
Cache é uma técnica para guardar dados temporariamente para que respostas futuras possam ser entregues mais rapidamente e com menos carga no servidor.
Em vez de “refazer o trabalho”, reutilizamos uma resposta já pronta.
📦 Onde o cache pode ser aplicado?
- Do lado do cliente (ex: browser)
- Num proxy ou CDN (ex: Cloudflare, Varnish)
- No servidor da API
- Dentro da aplicação (ex: Redis, memória local)
🔄 Exemplo prático
Imagina este pedido:
GET /artigos/populares
- Se o conteúdo muda apenas uma vez por hora, o servidor pode guardar a resposta em cache durante 60 minutos.
- Os próximos pedidos recebem a resposta sem recalcular nada.
🧠 Cabeçalhos HTTP usados para cache
Cache-Control
— Define quanto tempo a resposta pode ser guardadaETag
— Identificador único da versão do recurso (usado para validação)Last-Modified
— Data da última modificação (o cliente pode perguntar: “mudou desde então?”)
💡 Exemplo com Cache-Control
:
Cache-Control: public, max-age=3600
➡️ Qualquer cache pode guardar esta resposta por até 1 hora (3600 segundos).
🚀 Benefícios do cache
- ⚡ Melhora a performance (respostas mais rápidas)
- 📉 Reduz carga no servidor
- 📶 Melhora a experiência do utilizador
- 💰 Reduz custos de infraestrutura
⚠️ Quando não usar cache
- Para dados altamente dinâmicos (ex: saldo da conta bancária)
- Quando a informação é sensível ou personalizada (ex: histórico de compras)
💡 Em resumo
- Cache é um acelerador para APIs
- Bem configurado, oferece grandes ganhos de performance e escalabilidade
- Deve ser usado com critério para garantir consistência dos dados
🧑💻 Client: Quem faz o pedido à API
Um client (cliente) é qualquer entidade que envia um pedido a uma API.
Pode ser:
- Uma aplicação frontend (ex: aplicação em React / Angular / Vue / etc., app mobile, etc.)
- Outra API ou backend (ex: microserviços)
- Um terminal usando o
curl
- Um cliente HTTP como o Postman ou o Insomnia
- Um dispositivo (ex: IoT, smartwatch)
- Até scripts automatizados (bots, webhooks)
🔄 Como funciona a interação?
- O client constrói um pedido HTTP (com método, headers, corpo, etc.)
- Envia esse pedido ao endpoint da API
- A API processa, valida, executa a ação e devolve uma resposta
- O client interpreta a resposta e age em conformidade
📦 Exemplo simples
GET https://api.meusite.com/users/42
Authorization: Bearer xpto123
- O client faz o pedido
- O servidor responde com os dados do utilizador 42
- O client mostra essa informação num ecrã
🧠 O client também tem responsabilidades
- Montar pedidos corretamente
- Gerir erros (ex: 404, 500)
- Repetir pedidos em caso de falha (com backoff)
- Tratar autenticação e tokens
- Respeitar rate limits
🤝 Relação client–API
Uma API bem desenhada facilita a vida ao client:
- É previsível
- Dá mensagens de erro claras
- Tem boa documentação
- É estável e confiável
E um bom client respeita os limites, trata erros com elegância, e usa cache ou throttling quando necessário.
💡 Em resumo
- O client é o ponto de partida da comunicação com a API
- Pode ser qualquer sistema, app ou script que faça pedidos
- A relação entre client e API é uma parceria — cada um com responsabilidades
🎉 Considerações finais
Explorámos alguns conceitos essenciais para compreender o mundo das API’s — com exemplos, analogias e explicações práticas.
API’s não são só “uma coisa de programadores”.
Elas são uma cola invisível que faz o mundo digital funcionar. Que garante a comunicação entre aplicações e sistemas.
Agora que jáconheces estes conceitos, estás mais preparado para:
- Consumir APIs de forma eficiente
- Desenhar APIs mais intuitivas
- Explicar a quem pergunta: “mas o que é uma API, afinal?”