POST only? Acabemos com este absurdo debate sobre design de APIs
Desvendando o mito da API "POST only", explicando por que ele surge de uma má compreensão dos princípios de design de API e esclarecendo os casos de uso apropriados para estilos arquitetónicos RESTful e RPC.
Recentemente, uma discussão sobre se devemos desenhar APIs usando apenas "POST only" chamou a minha atenção. Depois de mergulhar neste debate, percebi que não apenas a questão sobre a qual as pessoas estão a discutir é sem sentido, como também revela o mal-entendido de muitos desenvolvedores sobre a essência do design de APIs. Hoje, vamos mergulhar nas ideias centrais do design de APIs e entender por que este debate não deveria existir.
O equívoco sobre "POST only"
Os desenvolvedores que defendem o uso exclusivo de "POST only" para substituir as especificações de APIs RESTful claramente não compreenderam o ponto mais importante do design de APIs. Os seus argumentos geralmente incluem:
- Simplificação do design: Um método pode lidar com tudo
- Segurança: Os parâmetros POST não aparecem na URL
- Flexibilidade: O POST pode enviar qualquer estrutura de dados
À primeira vista, esses argumentos parecem fazer algum sentido. Mas, na realidade, essa visão confunde a escolha de métodos HTTP com estilos de design de API, duas questões de níveis diferentes. POST é apenas um método do protocolo HTTP, enquanto REST é um estilo de design de API.
A essência do design de APIs
Antes de discutir estilos específicos de APIs, precisamos compreender o que é o propósito central do design de API. Uma boa API deve ser:
- Clara e compreensível: Outros desenvolvedores (incluindo o teu eu futuro) devem ser capazes de entender intuitivamente o propósito de cada endpoint
- Consistente: Seguir certas especificações para reduzir os custos de aprendizagem
- Extensível: Capaz de lidar facilmente com controlo de versão e expansão funcional
- Eficiente: Considerar a eficiência em termos de desempenho e utilização de recursos
API RESTful: Mais do que apenas uma escolha de métodos HTTP
API RESTful é apenas um dos muitos estilos de design de APIs, focando-se em recursos e operações sobre estes recursos. Vamos usar um sistema de blog simples como exemplo para ver como uma API RESTful é desenhada:
-
Obter todos os artigos:
-
Obter um artigo específico:
-
Criar um novo artigo:
-
Atualizar um artigo:
-
Apagar um artigo:
Neste exemplo, podemos ver:
- A API é desenhada em torno do recurso "artigo"
- Diferentes métodos HTTP são usados para representar diferentes operações
- A estrutura da URL é clara, indicando o recurso que está a ser operado
Esta abordagem de design torna a API mais intuitiva e autoexplicativa, facilitando a compreensão por parte dos desenvolvedores da função de cada endpoint.
RPC: Entendendo o estilo de API por trás do "POST only"
O objetivo do estilo de design de API RPC (Remote Procedure Call) é fazer com que chamadas de serviços remotos pareçam tão simples quanto chamar funções locais.
Curiosamente, aqueles que defendem o "POST only" podem não perceber que estão, na verdade, a descrever o estilo RPC.
Comparado às APIs RESTful, o RPC foca-se mais na operação em si do que no recurso. É por isso que as APIs no estilo RPC tipicamente usam uma forma "verbo + substantivo", como getProduct(productId)
ou createUser(userData)
.
Em muitas implementações RPC, todas as operações são geralmente enviadas através de pedidos de POST para o mesmo endpoint, com a operação específica e parâmetros especificados no corpo do pedido. É por isso que a ideia de "POST only" está na verdade mais próxima do RPC do que do REST.
Por exemplo, um pedido no estilo RPC para "obter produto" baseado em HTTP pode parecer assim:
Frameworks modernos de RPC, como gRPC, oferecem implementações mais poderosas e eficientes. Vamos usar este como exemplo para demonstrar o estilo RPC:
Primeiro, definimos o serviço e o formato de mensagens (usando Protocol Buffers):
Em seguida, usar este serviço num cliente Node.js é tão simples quanto chamar uma função local:
Neste exemplo no estilo RPC, podemos ver:
- A definição do serviço lista claramente todas as operações disponíveis (neste exemplo simplificado,
GetArticle
eCreateArticle
). - Cada operação tem tipos de pedido e resposta claramente definidos.
- O código do cliente parece uma chamada de função local assíncrona, usando
await
para aguardar pelo resultado, o que oculta ainda mais a complexidade da comunicação de rede. - Não há necessidade de construir manualmente pedidos HTTP ou analisar respostas JSON.
Apesar de a camada subjacente ainda poder usar HTTP/2 como protocolo de transporte, os frameworks RPC (como gRPC) fornecem uma camada de abstração que faz com que chamadas remotas pareçam e semelhem a chamadas de funções locais.
Portanto, podemos ver que a maioria dos debates sobre "POST only" e APIs RESTful deveriam, essencialmente, ser discussões sobre esses dois estilos de API: REST e RPC. No entanto, o fundamental é reconhecer que esses dois estilos têm cenários de aplicação próprios, e a escolha deve ser baseada nas necessidades específicas do projeto, e não em preferências pessoais.
REST vs RPC: Não há superioridade ou inferioridade absolutas
Agora que entendemos as diferenças entre REST e RPC, vamos ver os seus respetivos cenários de aplicação:
- REST é adequado para:
- Aplicações orientadas a recursos (como sistemas de gestão de conteúdo, plataformas de blog, websites de comércio eletrónico)
- Cenários que exigem bom suporte a cache (pedidos GET são naturalmente cacheáveis)
- Projetos que desejam aproveitar as semânticas do HTTP (como usar códigos de estado apropriados)
- APIs de uso público que requerem boa descoberta e auto-descrição
- RPC é adequado para:
- Aplicações orientadas a ações (como operações complexas de processamento de dados, controlo de fluxo de trabalho)
- Sistemas que exigem alta performance e baixa latência (como sistemas de negociação em tempo real)
- Comunicação entre microsserviços internos (que podem necessitar de passagem de parâmetros mais flexível)
- Quando operações não podem ser simplesmente mapeadas para operações CRUD (Create, Read, Update, Delete)
A escolha do estilo deve ser baseada nas tuas necessidades específicas. Em alguns casos, podes até utilizar uma mistura desses dois estilos dentro do mesmo sistema para atender às necessidades de diferentes partes.
Conclusão
- O mais importante no design de API é a clareza, consistência, extensibilidade e eficiência, e não a adesão a um método ou estilo específico.
- Tanto RESTful quanto RPC são paradigmas de design de API maduros. A escolha entre eles deve ser feita com base nos requisitos do projeto, e não por preferência pessoal.
- Se decidires usar "POST only", então, por favor, desenha a tua API de acordo com o estilo RPC. Assim como o RESTful, é uma especificação de API amplamente utilizada na indústria, mas deve ser usada em cenários apropriados.
- Não te deixes confundir pelos detalhes técnicos superficiais. O que realmente importa é se a tua API pode servir de forma eficaz os teus utilizadores e necessidades de negócio.
- Ao desenhar APIs, dedica mais tempo a pensar no teu modelo de recursos, lógica de negócios e necessidades dos utilizadores, em vez de te fixares sobre qual método HTTP usar.
Vamos desviar a atenção destes argumentos sem sentido e focarmo-nos em desenhar APIs verdadeiramente excelentes. Afinal, a tecnologia existe para resolver problemas, não para os criar.