Alguns conceitos sobre API’s que devias conhecer

Francisco Costa
23 min readMay 4, 2025

--

É 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 utilizadores
  • GET /users/42 → Detalhes do utilizador com ID 42
  • PUT /users/42 → Atualizar o utilizador 42
  • DELETE /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 dados
  • POST → Criar algo novo
  • PUT → Atualizar algo existente
  • DELETE → 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 sucesso
  • 400 Bad Request – Erro no pedido
  • 404 Not Found – O recurso não existe
  • 500 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 de 400 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 ou 422
  • 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ágina
  • offset=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 2
  • per_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:

  • GETObter dados — Read
  • POSTCriar novos dados — Create
  • PUTAtualizar dados — Update
  • PATCHAtualizar parcialmente — Update (parcial)
  • DELETEApagar 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 headerLocation 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 e preco_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 permitidos
  • X-RateLimit-Remaining: Quantos ainda podes fazer
  • X-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

  1. One-way — Uma app envia dados à outra (ex: notificações)
  2. Two-way (bidirecional) — Ambas enviam e recebem dados (ex: sincronização de dados)
  3. Síncrona — Uma app espera resposta imediata
  4. 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:

  • CreatePOST
    POST /users
    — Cria um novo utilizador
  • ReadGET
    GET /users/123
    — Lê os dados do utilizador 123
  • UpdatePUT / PATCH
    PUT /users/123
    — Atualiza os dados do utilizador 123
  • DeleteDELETE
    DELETE /users/123
    — Apaga o utilizador 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 guardada
  • ETag— 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?

  1. O client constrói um pedido HTTP (com método, headers, corpo, etc.)
  2. Envia esse pedido ao endpoint da API
  3. A API processa, valida, executa a ação e devolve uma resposta
  4. 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?”

--

--

Francisco Costa
Francisco Costa

Written by Francisco Costa

Hello, I'm Francisco Costa. I'm a software engineer living in Lisbon, Portugal.

No responses yet