Visão geral
A loja tem um front-end web, um aplicativo mobile e um serviço de pedidos, e os três precisam dos dados de produtos mantidos pelo serviço de produtos. Como cada um deles sabe qual URL chamar, o que enviar e o que recebe de volta? E o que acontece com eles quando o time de produtos reescrever o serviço no próximo semestre? A resposta para as duas perguntas é a API.
Uma API (Application Programming Interface) é um contrato que define como dois componentes de software se comunicam. Ela especifica quais operações estão disponíveis, quais entradas aceitam e quais saídas retornam — sem expor a implementação interna.
No contexto de microsserviços, as APIs são o principal mecanismo de integração: os serviços expõem APIs, os clientes as consomem, e os times evoluem cada lado de forma independente, desde que o contrato seja respeitado. Uma fronteira de API estável significa que a implementação por trás dela pode ser totalmente substituída sem impactar nenhum consumidor.
flowchart LR
consumer["Cliente\n(mobile, navegador, serviço)"]
api["API\n(contrato)"]:::highlighted
impl["Implementação\n(linguagem, BD, framework)"]
consumer -->|"requisição"| api
api -->|"resposta"| consumer
api -->|"esconde"| impl
consumer -.-x|"não enxerga"| impl
classDef highlighted fill:#fcc Objetivos de aprendizagem
Ao final desta aula, você deve ser capaz de:
- Explicar por que um contrato de API estável permite que os times alterem e façam o deploy de serviços de forma independente.
- Comparar APIs REST, gRPC, GraphQL, WebSocket e baseadas em mensagens, e escolher uma para uma dada interação.
- Projetar um recurso REST com URIs, métodos HTTP, códigos de status, corpos de erro e paginação corretos.
- Distinguir uma mudança incompatível (breaking change) de uma retrocompatível, e versionar uma API quando necessário.
- Documentar um serviço Spring Boot com OpenAPI e Swagger UI, e decidir onde a documentação pode ser exposta.
Roteiro
- Esta página — o que é um contrato de API, por que ele importa, os principais estilos de API e quão RESTful uma API é.
- Design de APIs REST — recursos, métodos, idempotência, códigos de status, erros, paginação e versionamento.
- OpenAPI & Swagger — descrever o contrato em um documento legível por máquina e servi-lo com o springdoc.
Slides
Clique nos slides e use ← → para navegar; F abre em tela cheia e P abre a visão do apresentador, com as notas. Abrir os slides em uma nova aba
Por que APIs importam
| Sem uma API estável | Com um contrato de API estável |
|---|---|
| Toda mudança interna corre o risco de quebrar os consumidores | Os consumidores ficam isolados das mudanças de implementação |
| Os times precisam coordenar cada deploy | Os times fazem deploy de forma independente |
| Erros de integração aparecem em tempo de execução | O contrato pode ser testado antes da integração |
| A documentação se desatualiza e fica obsoleta | O contrato é a única fonte da verdade |
O contrato na nossa plataforma
O hands-on torna o contrato concreto. No Hands-on 1, o microsserviço Account é dividido em dois módulos Maven:
| Módulo | Contém | Quem depende dele |
|---|---|---|
account | o contrato: a interface AccountController (POST /accounts, GET /accounts/{id}…) e os DTOs AccountIn / AccountOut | a implementação e todos os clientes — o serviço de autenticação chama accounts por meio dele, como um cliente OpenFeign |
account-service | a implementação: AccountResource, AccountService, o modelo JPA AccountModel e o repositório | ninguém — ele é privado do time de accounts |
Como o serviço de autenticação (Hands-on 3) depende apenas do módulo account, o time de accounts pode mudar livremente o banco de dados, o modelo ou a lógica do serviço. Apenas uma mudança em AccountController, AccountIn ou AccountOut é visível para os outros — e é exatamente essa a mudança que precisa ser negociada e, se quebrar clientes, versionada (veja Versionamento).
Termos usados nesta aula
- Consumidor (ou cliente): o código que chama a API — um navegador, um aplicativo mobile ou outro serviço.
- Provedor: o serviço que implementa a API.
- Endpoint: uma operação da API, identificada por um método HTTP e um caminho, como
GET /accounts/{id}. - DTO (Data Transfer Object): uma classe cuja única função é transportar dados através da fronteira da API —
AccountIn,AccountOut. Ela é deliberadamente diferente da entidade do banco de dados.
Tipos de APIs
| Estilo | Protocolo | Formato | Uso típico |
|---|---|---|---|
| REST | HTTP/1.1 ou HTTP/2 | JSON / XML | APIs web públicas e internas — a escolha dominante |
| gRPC | HTTP/2 | Protocol Buffers (binário) | Chamadas internas de alto desempenho entre serviços |
| GraphQL | HTTP | JSON | Consultas flexíveis guiadas pelo cliente; padrão Backend for Frontend (BFF) |
| WebSocket | Protocolo WebSocket (começa como um Upgrade HTTP, depois full-duplex sobre TCP) | Qualquer | Comunicação bidirecional em tempo real — chat, feeds ao vivo, colaboração |
| Baseado em mensagens | AMQP / protocolo do Kafka | JSON / Avro | Integração assíncrona orientada a eventos entre serviços |
A mesma operação — "me dê o produto 42" — fica bem diferente em cada um dos três estilos de requisição/resposta:
A URL identifica o recurso e o método HTTP diz o que fazer. Qualquer cliente HTTP (navegador, curl, Postman) consegue chamá-la.
service ProductService {
rpc GetProduct (GetProductRequest) returns (Product);
}
message GetProductRequest { string id = 1; }
message Product { string id = 1; string name = 2; double price = 3; }
O contrato é um arquivo .proto; o código é gerado para cliente e servidor, e as mensagens trafegam em binário compacto. Chamá-la exige um cliente gRPC — um navegador não consegue chamá-la diretamente.
Como escolher. Para a API pública da loja (navegadores, aplicativos mobile, parceiros), REST é o padrão: ferramentas universais, GETs cacheáveis, fácil de depurar. gRPC compensa em chamadas internas frequentes, em que a latência e o tamanho do payload importam. GraphQL se encaixa em um front-end que compõe dados de muitos serviços. Mensageria é a escolha quando o produtor não deve esperar pelo consumidor — tema de Arquitetura Orientada a Eventos.
Maturidade REST (Modelo de Richardson)3
Nem todas as APIs HTTP são igualmente RESTful. Leonard Richardson definiu um modelo de maturidade com quatro níveis:
| Nível | Característica | Exemplo |
|---|---|---|
| 0 — Swamp of POX | Um único endpoint para todas as operações | POST /service?op=getOrder |
| 1 — Recursos | URIs separadas por recurso | GET /orders/42 |
| 2 — Verbos HTTP | Uso correto de GET, POST, PUT, DELETE + códigos de status | DELETE /orders/42 → 204 |
| 3 — Hipermídia (HATEOAS) | As respostas incluem links para as próximas ações possíveis | "links": [{"rel": "cancel", "href": "/orders/42/cancel"}] |
POX significa "Plain Old XML": a requisição HTTP é só um túnel para uma chamada de procedimento remoto. HATEOAS significa "Hypermedia As The Engine Of Application State": o cliente descobre o que pode fazer em seguida a partir dos links na resposta, como uma pessoa faz ao navegar em um site.
A maioria das APIs REST em produção opera no nível 2. O nível 3 é raro na prática, tanto em microsserviços internos quanto em APIs públicas; a API REST do PayPal é um exemplo conhecido que retorna links com rel e href nas respostas.
Este curso foca em REST nível 2 e na documentação de APIs com OpenAPI / Swagger.
Armadilhas comuns ao projetar uma API
- Vazar a implementação: retornar a entidade JPA diretamente expõe colunas como o hash da senha e amarra o contrato ao esquema do banco de dados. Use DTOs (
AccountOutnão tem senha). - APIs "tagarelas" (chatty): uma tela que precisa de dez chamadas para ser renderizada fica lenta através da rede; projete os recursos em torno do que os consumidores precisam.
- Mudanças incompatíveis silenciosas: renomear um campo JSON é invisível para os testes do próprio provedor, mas quebra todos os consumidores. Trate o contrato como público — veja Versionamento.
- RPC disfarçado de REST: verbos na URL (
/createOrder) colocam a API no nível 0–1 de Richardson.
Tópicos abordados
-
Design de APIs REST
Métodos HTTP, códigos de status, convenções de URL, estrutura de requisição e resposta, versionamento e os princípios de design que tornam as APIs previsíveis e fáceis de consumir.
-
OpenAPI & Swagger
Documentação de APIs com a especificação OpenAPI. Integração do Swagger UI a um serviço Spring Boot para que a documentação da API esteja sempre sincronizada com o código.
Pontos-chave
- Uma API é um contrato: os consumidores dependem dele, nunca da implementação por trás dele.
- No hands-on, o contrato é um módulo separado (
account: interface + DTOs) da implementação (account-service). - REST sobre HTTP é o padrão para APIs web; gRPC, GraphQL, WebSocket e mensageria resolvem necessidades específicas.
- A maioria das APIs está no nível 2 de Richardson: recursos + métodos HTTP + códigos de status. REST foi definido por Roy Fielding2 sobre a semântica do HTTP1.
- Nunca exponha entidades; mudar um DTO é mudar o contrato.
Conexões
- Construa o contrato e sua implementação: Hands-on 1 — CRUD.
- Encaminhe clientes externos para as APIs: Hands-on 2 — Gateway.
- Projete suas próprias APIs: exercícios Product API e Order API.
- APIs assíncronas: Arquitetura Orientada a Eventos. Como os serviços se encaixam: Microsserviços.
-
FIELDING, R. T. Architectural Styles and the Design of Network-based Software Architectures. Tese de doutorado, UC Irvine, 2000. (Definição original de REST.) ↩
-
FOWLER, M. Richardson Maturity Model. martinfowler.com, 2010. ↩