O autor critica alguns aspectos das APIs RESTful, como sua dependência de JSON que pode ser ineficiente em termos de largura de banda, a falta de esquemas e contratos formais, e a limitação do modelo CRUD para representar complexos domínios de negócios. Ele argumenta que alternativas como protocolos binários podem ser mais eficientes, e que REST não é sempre a abordagem mais adequada.
1. RESTful considerada
prejudicial – Parte 1
APIs RESTful são comuns em toda a internet, mas isso é
uma coisa boa?
Eu não gosto de princípios e APIs RESTful. Nos últimos anos, ele
é visto como o protocolo universal para comunicação entre
processos, especialmente em sistemas distribuídos. No entanto
eu vejo muitas deficiências de REST e existem alternativas que
funcionam bem para certos casos de uso. Obviamente, não
existe um tamanho único, eu só quero enfatizar que a arquitetura
REST é falho em um número de maneiras.
Inchado, um formato legível que Exige
compressão extra
O formato padrão de facto para REST é JSON. Pelo menos é
muito melhor do que o sabão com o seu XML e envelopes. Quer
muita largura de banda de rede é perdido (pode ser um problema
com dispositivos móveis ou grandes centros de dados) ou CPU é
gasto na compressão e descompressão. Uma bela citação:
[A] internet está sendo executado em fonte modo de depuração
É um problema sério, pergunte operadores de alta frequência
como duramente parsing FIX baseado em texto é. Há uma
abundância de bem estabelecido protocolos binários que são
ambos fácil de analisar e utilizar pouca memória, por exemplo,
buffers de protocolo, Avro ou poupança. Além disso
compatibilidade com versões anteriores é construído para eles.
Pode ser tecnicamente usando o Google Protocol Buffers com
serviços REST baseados em MVC Spring - mas de alguma forma
muito poucos fazê-lo desta forma e ficar com JSON.
Claro JSON tem uma (literalmente, um) enorme vantagem - é
legível. Bem, pelo menos enquanto é bastante impressa -
raramente o caso. Mas será que realmente querem pagar esse
2. preço, em vez de apenas usar o formato binário por padrão e tem
tradutor ou mudar quando a intervenção humana é necessária?
Nem esquema Nem Contrato
Eu pertenço ao campo de tipagem estática. Eu adoro quando
meu compilador encontra erros antes mesmo de eu executar
testes de unidade - e que eu não preciso escrever tantos deles
em primeiro lugar. Além disso, especialmente na programação
funcional se o código compila, é possível que ele funciona porque
o contrato imposta pelos tipos é tão rigorosa. Ao lidar com XML
Estou feliz por ter XSD validados para que eu possa ter certeza
de que eu li conforma com o contrato. Posso reduzir o número de
afirmações e manter o código mais curto. Além disso, o XML eu
produzo é garantido para ser sintaticamente correto. Por último,
mas não menos importante quando se trabalha com bancos de
dados relacionais do esquema rigoroso me impede de corrupção
de dados através da inserção de valores incorretos. À
semelhança do XML, eu também posso confiar no que eu li:
chaves estrangeiras estão corretas, colunas NOT NULL
realmente não são null, etc Estas são claramente as vantagens
do contrato de máquina aplicada. De alguma forma, tudo isso não
é importante mais ao projetar API a ser produzida e consumida
pelas máquinas em um sistema distribuído (e, acidentalmente,
em muitos bancos de dados NoSQL sem esquema como
MongoDB).
ódio compreensível do SOAP nos empurrou para outro extremo -
sem contrato em tudo. Não há um padrão generalizado para
documentar contratos e aplicá-las automaticamente para APIs
REST. A maioria das APIs I encontrar estes dias são apenas uma
coleção de solicitações de amostras e respostas, Swagger na
melhor das hipóteses. Eu nunca sei quais os campos são
opcionais, quais são os formatos e restrições. Alguém poderia
argumentar que isso é por design, que não fazer par-nos a um
API de concreto, permitindo que ela evolua. Mas tenho a
sensação de que a maioria dos consumidores de API são, no
entanto, acoplado e vai quebrar uma vez em situação irregular e
alteração sem aviso prévio é desenrolado.
Publishing URIs
3. Falando sobre a documentação, os puristas afirmam que a única
peça de API informações devem expor é a raiz URI, por exemplo,
www.example.com/api.Tudo o resto, incluindo métodos, recursos, tipos e
documentos de conteúdo permitida devem ser descoberto
através HATEOAS. E se URIs não são oficialmente documentado
mas em vez disso deve ser descoberto, isso implica que não
deve confiar em URIs codificados em nosso código, mas sim
percorrer a árvore de recursos cada vez que utilizar essa API.
Este é idiomática, no entanto, também lento e sujeito a erros.
Sem mencionar Swagger, o padrão de fato para a documentação
REST, afirma oficialmente tal abordagem "não é por o projeto" - e
paus para URIs fixo.
Não há suporte para dosagem, Pager,
Classificação / Searching, ...]
serviço web RESTful não suporta nativamente muitos recursos de
nível empresarial de APIs como pedidos de lotes, paginação,
classificação, pesquisa e muitos outros. Há sugestões de
concorrentes, como parâmetros de consulta, cabeçalhos de
solicitação, etc. Lembro-me de uma longa discussão sobre horas
flexíveis de busca API tivemos há algum tempo. Deve haver:
single SQL-like parameter (with proper escaping!),
e.g. query=age>10 and (name=John or company=Foo)
multiple parameters for each criteria,
e.g. age=10&name=John&company=Foo (but how to
implement OR operator?)
most bizarre: stateful POST on /searches with criteria modeled
with JSON-like structure, returning URL to search results
(/searches/25), which can later be queried
REST está realmente constrangedora aqui.
CRUD por Definição
serviços Web RESTful são CRUD-orientado, em vez de
Business- ou orientada a transação. Inúmeras vezes tivemos
para mapear cuidadosamente os termos do negócio em simples
4. criar / update / delete ações. Mundo não é assim tão simples e
nem tudo pode ser simplesmente descrito em criar ou frases de
atualização. E mesmo se ele pode, muitas vezes endpoints
RESTful são terrivelmente estranho e artificial. Você ainda se
lembra POST para /searches ?
Além disso nem todos os dados podem ser mapeados em
estrutura de árvore URI e muitas vezes nós permitimos
desnormalização, por exemplo, o mesmo recurso está disponível
sob várias URIs de modo que seja facilmente acessível.
Imagine um sistema que publica eventos de domínio, alterações
de estado arbitrários, por exemplo:
LoanApproved, EmailSent, etc. É claro que cada evento tem seu próprio
conjunto, distinta de atributos. Como você projeta uma API
RESTful que consome tais eventos? Inevitavelmente você vai
acabar com POST /domainEvents que aceita JSON arbitrária, talvez
com algum tag como "type": "LoanApproved". Então você tem um ponto
de extremidade que leva arbitrária "BLOB" JSON e,
provavelmente, tem uma declaração gigante switch-como
interpretar vários tipos de eventos corretamente. Substituir "type"
com"method" e você só reinventou JSON RPC. Como você fazer
isso de uma forma idiomática? Traduzir cada evento de domínio
no lado do editor de chamada de API apropriada? Não soa muito
robusto.
Verbos HTTP não são suficientemente
descritivo
Mapeamento de termos de negócios em
POST/PUT/PATCH/DELETE/HEAD é tedioso e infantil. Assim
como com URIs, mundo é muito mais rica e nem tudo se encaixa
esses baldes. Esses verbos foram projetados para interagir com
documentos e formulários em World Wide Web. Usando REST
parece degradar o nosso domínio do negócio de volta para o
navegador de banco de dados. Não há lógica, não Domain-
Driven Design, há fluxos ricos. Nós simplesmente manipular
objetos, transferi-los para trás e para frente. Claro RESTO não
precisa e não deve mapear diretamente para entidades de banco
de dados. Mas mesmo se eles são mapeados para o seu domínio
5. de negócio core, você ainda tem que ver o seu domínio através
de interface CRUD limitado.