Hypermedia APIs: REST do jeito que Roy Fielding realmente quis dizer
1. O que é REST de verdade? Desconstruindo o mito do CRUD via HTTP
Quando desenvolvedores dizem "estou construindo uma API REST", na maioria das vezes estão apenas criando endpoints que mapeiam operações CRUD para verbos HTTP. Isso não é REST. É RPC disfarçado.
Roy Fielding, em sua tese de doutorado de 2000, definiu seis constraints arquiteturais que formam o REST verdadeiro: cliente-servidor, stateless, cache, interface uniforme, sistema em camadas e code-on-demand (opcional). O coração do sistema é a interface uniforme, que exige identificação de recursos, manipulação via representações, mensagens auto-descritivas e — o mais ignorado — hypermedia como motor do estado da aplicação.
Sem hypermedia, sua API é apenas uma coleção de endpoints fixos que o cliente precisa conhecer previamente. Isso viola o princípio fundamental de REST: o servidor deve guiar o cliente através das transições de estado possíveis.
2. HATEOAS: Hypermedia as the Engine of Application State
HATEOAS significa que o servidor entrega não apenas dados, mas também instruções sobre o que o cliente pode fazer em seguida. Em vez de o cliente saber que POST /orders cria um pedido, o servidor inclui um link ou formulário na resposta que indica essa possibilidade.
Considere uma resposta tradicional:
GET /orders/123
{
"id": 123,
"status": "pending",
"total": 150.00
}
Agora, a mesma resposta com HATEOAS:
GET /orders/123
{
"id": 123,
"status": "pending",
"total": 150.00,
"_links": {
"self": { "href": "/orders/123" },
"pay": { "href": "/orders/123/payments", "method": "POST" },
"cancel": { "href": "/orders/123", "method": "DELETE" },
"items": { "href": "/orders/123/items" }
}
}
O cliente descobre dinamicamente que pode pagar ou cancelar o pedido. Se o status mudar para "paid", o servidor remove o link "pay" e adiciona "refund". A navegação é guiada, não hardcoded.
3. Formatos de Hypermedia: HAL, Siren, JSON:API e Collection+JSON
HAL (Hypertext Application Language) é o formato mais simples. Usa _links para navegação e _embedded para recursos embutidos:
GET /books/42
{
"_links": {
"self": { "href": "/books/42" },
"author": { "href": "/authors/7" },
"reviews": { "href": "/books/42/reviews" }
},
"title": "RESTful Web APIs",
"isbn": "978-1449358068",
"_embedded": {
"author": {
"_links": { "self": { "href": "/authors/7" } },
"name": "Roy Fielding"
}
}
}
Siren é mais rico, com actions que descrevem formulários completos:
{
"class": [ "order", "pending" ],
"properties": { "total": 150.00 },
"actions": [
{
"name": "pay",
"method": "POST",
"href": "/orders/123/payments",
"fields": [
{ "name": "payment_method", "type": "text" },
{ "name": "amount", "type": "number" }
]
}
],
"links": [
{ "rel": [ "self" ], "href": "/orders/123" }
]
}
JSON:API oferece relações, includes e paginação via links. Collection+JSON é focado em coleções com templates de consulta e edição.
Escolha HAL para simplicidade, Siren para APIs com workflows complexos, JSON:API para compatibilidade com ecossistemas existentes e Collection+JSON para APIs centradas em listas e filtros.
4. Navegabilidade e Descoberta: Clientes que aprendem com o servidor
Um cliente genérico de hypermedia não precisa de documentação de endpoints. Ele começa com uma URL raiz e segue links. Exemplo de fluxo de checkout:
GET /api/
{
"_links": {
"products": { "href": "/api/products" },
"cart": { "href": "/api/cart" }
}
}
GET /api/products
{
"_links": { "self": { "href": "/api/products" } },
"items": [
{
"name": "Livro REST",
"_links": {
"add-to-cart": { "href": "/api/cart/items", "method": "POST" }
}
}
]
}
O cliente descobre que pode adicionar ao carrinho. Após adicionar, a resposta do carrinho inclui:
{
"_links": {
"checkout": { "href": "/api/checkout", "method": "POST" }
}
}
Sem hardcode de URLs. Se o servidor mudar os endpoints, o cliente se adapta automaticamente, desde que os links sejam seguidos.
5. Hypermedia na prática: Implementando uma API de livros com HATEOAS
Vamos modelar uma API de livros onde cada recurso expõe apenas ações permitidas pelo estado atual.
Recurso livro (disponível):
GET /books/1
{
"id": 1,
"title": "RESTful Web APIs",
"status": "available",
"authors": ["Roy Fielding"],
"_links": {
"self": { "href": "/books/1" },
"borrow": { "href": "/books/1/borrow", "method": "POST" },
"update": { "href": "/books/1", "method": "PATCH" },
"delete": { "href": "/books/1", "method": "DELETE" }
}
}
Após emprestar (emprestado):
GET /books/1
{
"id": 1,
"title": "RESTful Web APIs",
"status": "borrowed",
"borrowed_by": "user123",
"due_date": "2025-04-15",
"_links": {
"self": { "href": "/books/1" },
"return": { "href": "/books/1/return", "method": "POST" },
"extend": { "href": "/books/1/extend", "method": "POST" }
}
}
Note que os links "borrow", "update" e "delete" desapareceram. O servidor guia o cliente apenas para ações válidas. O código do servidor verifica o estado e gera os links dinamicamente:
function getBookLinks(book, user) {
const links = { self: { href: `/books/${book.id}` } };
if (book.status === 'available') {
links.borrow = { href: `/books/${book.id}/borrow`, method: 'POST' };
if (user.role === 'admin') {
links.update = { href: `/books/${book.id}`, method: 'PATCH' };
links.delete = { href: `/books/${book.id}`, method: 'DELETE' };
}
} else if (book.status === 'borrowed' && book.borrowed_by === user.id) {
links.return = { href: `/books/${book.id}/return`, method: 'POST' };
links.extend = { href: `/books/${book.id}/extend`, method: 'POST' };
}
return links;
}
6. Desafios reais: Performance, versionamento e adoção no mercado
Overhead de payload: Respostas com hypermedia podem ser 30-50% maiores. Soluções: compressão HTTP, campos opcionais via query params (?embed=links), ou formatos binários como CBOR.
Versionamento: Hypermedia permite evolução sem quebrar clientes. Em vez de /v1/books, o servidor adiciona novos links e mantém os antigos. Clientes antigos ignoram links desconhecidos. Isso é versionamento evolutivo.
Adoção no mercado: Poucas equipes adotam HATEOAS porque:
- Clientes precisam ser mais inteligentes
- Ferramentas como Swagger/OpenAPI incentivam endpoints fixos
- A maioria dos desenvolvedores nunca leu a tese de Fielding
Para superar: comece com HAL em endpoints críticos, use ferramentas de validação de hypermedia (como Hyperium) e documente os relation types (rel) em vez de URLs.
7. O futuro das Hypermedia APIs: GraphQL, JSON:API e o renascimento do REST
GraphQL não é hypermedia. Ele oferece descoberta via schema introspection, mas o cliente decide a estrutura da resposta e as transições de estado não são guiadas pelo servidor. É uma ferramenta poderosa, mas diferente.
JSON:API está evoluindo para incluir mais hypermedia. A especificação 1.1 adicionou links obrigatórios em recursos e suporte a meta com actions. É a ponte mais prática entre REST tradicional e HATEOAS.
Tendências: APIs auto-descritivas com máquinas de estado explícitas (como JSON State Machine ou State Charts) estão ganhando espaço. Ferramentas como Hydra e JSON-LD permitem descrições semânticas completas dos recursos.
O renascimento do REST verdadeiro virá quando entendermos que hypermedia não é um extra opcional — é a alma do REST. Sem ele, temos apenas RPC com verbos HTTP.
Referências
- A Fielding, "Architectural Styles and the Design of Network-based Software Architectures" (Tese original) — A tese de doutorado de Roy Fielding que define os princípios fundamentais do REST, incluindo o constraint de hypermedia.
- HAL Specification (Hypertext Application Language) — Especificação oficial do formato HAL para representação de recursos com links e recursos embutidos.
- Siren: A Hypermedia Specification for Representing Entities — Documentação do formato Siren, que adiciona actions e classes semânticas às entidades hypermedia.
- JSON:API Specification — Especificação oficial do JSON:API, incluindo suas extensões para links, relações e paginação hypermedia.
- RESTful Web APIs (O'Reilly) — Livro de Leonard Richardson e Mike Amundsen que aprofunda a implementação prática de HATEOAS e hypermedia APIs.
- Hypermedia REST APIs: The Missing Manual — Artigo da InfoQ que discute os desafios reais de adoção de hypermedia e estratégias para implementação gradual.