Pelo livro REST vs Demasiadas solicitações

8

Do comentário de Roy Fielding em seu próprio artigo, descriptografando APIs falsas do REST :

Uma API verdadeiramente RESTful se parece com hipertexto. Toda unidade de informação endereçável carrega um endereço, explicitamente (por exemplo, atributos de link e ID) ou implicitamente (por exemplo, derivado da definição de tipo de mídia e estrutura de representação). Os resultados da consulta são representados por uma lista de links com informações resumidas, não por matrizes de representações de objetos (a consulta não substitui a identificação de recursos).

Isso significa que, se você precisar, digamos, consultar uma lista dos 100 usuários logados mais recentemente e exibir seus nomes e e-mails, precisará primeiro fazer uma GETconsulta à lista de resultados, o que (essencialmente) seja uma lista de elementos de link, com cada objeto de link contendo o URI de um recurso do usuário. Você precisaria fazer mais 100 GETsolicitações - uma para cada recurso do usuário - antes de ter os dados necessários para exibir seus resultados.

Isso parece incrivelmente ineficiente. Não há realmente nenhuma outra maneira verdadeiramente RESTful de obter os dados necessários em 1 ou 2 solicitações?

Jonah
fonte
1
Você não perdeu a parte: "com informações resumidas"?
Luc Franken
1
Eu não senti falta disso, mas "informações resumidas" implica "resumo" para mim, não "todos os dados". Ele diz especificamente "não por matrizes de representações de objetos" - que é exatamente o que precisamos para nossa exibição.
Jonah
1
Vemos a lista como um recurso e, para nós, contém campos como: link para recurso único, título, descrição curta e número de comentários, por exemplo. Não incluímos objetos completos porque eles são grandes demais. Portanto, nossos recursos de lista fornecem todas as informações necessárias para usá-lo. Quando você deseja mais, carrega o recurso completo, que pode incluir formulários, muito conteúdo e outras partes maiores. Tentamos uma vez incluir todos os recursos (processo de pensamento da YAGNI) na íntegra, mas isso quebrou. Então adicionamos esta etapa. E acho que é totalmente REST, uma lista de informações é um recurso por si só.
Luc Franken
Não tente aplicar estritamente (cegamente) frases de campo sobre o REST. É claro que ele é o pai da arquitetura REST, mas tenha cuidado: a arquitetura REST é para sistemas de alta escalabilidade, por isso foi inferida a partir da Web. Se fizer sentido usar uma matriz de objetos para problemas de desempenho, vá em frente.
AilurusFulgens
HAL + json é geralmente considerado RESTful. Ele inclui uma versão reduzida (resumo) dos objetos e um link para o recurso completo.
precisa

Respostas:

7

Não há realmente nenhuma outra maneira verdadeiramente RESTful de obter os dados necessários em 1 ou 2 solicitações?

  • Na verdade não
  • Mas não pense demais

Como de costume, ao pensar em REST, lembre-se de que há uma implementação de referência (a World Wide Web) que você pode verificar.

Considere o portal da Amazon - quando abro esse marcador com um cache vazio, vejo meu navegador fazer solicitações para 275 recursos.

Eu obteria uma latência melhor se todo esse estado fosse buscado em uma única carga útil? Sim.

Escalaria? seria escala na web? Provavelmente não. São 4,5 MB de dados que não podem ser compartilhados porque incluem 1 KB específico para o meu perfil. Se meu colega na mesa ao meu lado também for para a Amazon, ele puxa os mesmos dados pela rede.

Decomponha essa carga útil em recursos endereçáveis ​​individualmente e, de repente, as coisas ficarão muito melhores - cada um de nós ainda terá 1KB de personalização e cada um de nós ainda terá nossa cópia local de 4,5 MB em cache local, mas não precisamos interromper a rede tão difícil, porque a maioria das nossas solicitações foi atendida por um cache compartilhado local, em vez de precisar rotear pela Internet.

Além disso, lembre-se de que você realmente não tem um problema com vários recursos , mas com vários pedidos . Isso pode ser atenuado usando HTTP / 2.0 Push Promises , com o servidor enviando proativamente representações que podem ser armazenadas em cache. Talvez - um servidor sem estado não saiba o que o cliente armazenou em cache e o TLS sugere que o cache em intermediários não é uma prioridade ...

Isso significa que, se você precisar, digamos, consultar uma lista dos 100 usuários conectados mais recentemente e exibir seus nomes e e-mails, precisará primeiro fazer uma consulta GET para a lista de resultados, o que (essencialmente ) seja uma lista de elementos de link, com cada objeto de link contendo o URI de um recurso do usuário. Você precisaria fazer mais 100 solicitações GET - uma para cada recurso do usuário - antes de ter os dados necessários para exibir seus resultados.

Obviamente, se você estivesse fazendo isso em html, sua representação dos usuários mais recentes provavelmente seria um documento com uma lista ou uma tabela de nomes e endereços de email e links para esses recursos. Ta-da.

Não perca essa observação de Fielding.

Isso não significa que acho que todos deveriam projetar seus próprios sistemas de acordo com o estilo de arquitetura REST. O REST é destinado a aplicativos baseados em rede de longa duração que abrangem várias organizações. Se você não perceber a necessidade das restrições, não as use.

EDITAR

posso fazer o mesmo argumento para uma representação JSON? ou seja, se o recurso em questão for "100 últimos usuários conectados" em vez de resultados de uma consulta parametrizada, posso retornar os dados em vez de links de recursos? se não, por que? por que o JSON é essencialmente diferente do HTML nesse sentido?

Como eles são parecidos: compactar mais dados na "lista de resultados" economiza os custos de solicitações adicionais, comprometendo a escala. O tipo de mídia específico que você está usando para a representação não importa - pelo menos, tanto quanto eu saiba.

Como eles são diferentes: HTML é um formato hipermídia, e JSON não - qualquer implementação padrão de cliente familiar que esteja familiarizada com as especificações HTML saberá como encontrar os links em um documento HTML, que suporta opções como pré-busca. O JSON não possui essa padronização - você precisa de informações fora da banda sobre a estrutura de dados para entender onde os links estão em uma representação JSON. O HAL seria uma correspondência mais próxima do HTML a esse respeito; a principal diferença entre HAL e HTML é adoção; O HTML tem um avanço de 20 anos?

Para obter informações adicionais, considere também revisar o Atom Syndication Format , que descreve Entradas e Feeds (listas de Entradas), especialmente as regras da atom: entry , que podem ser acessadas por um recurso independente ou por um recurso de feed.

VoiceOfUnreason
fonte
1
O último parágrafo de Fielding deve ser gravado na testa de todos os pedantes do REST no texto reverso, para que eles possam vê-lo toda vez que se olharem no espelho.
21716 Robert Harvey
ótima resposta, como de costume. re: seu último parágrafo em uma representação HTML, posso apresentar o mesmo argumento para uma representação JSON? ou seja, se o recurso em questão for "100 últimos usuários conectados" em vez de resultados de uma consulta parametrizada, posso retornar os dados em vez de links de recursos? se não, por que? por que o JSON é essencialmente diferente do HTML nesse sentido?
Jonah
@Jonah JSON não é um formato hipermídia, ao contrário do HTML (e alguns outros). Um formato hipermídia permite descrever links e relações. Em HTML, você faz isso com <a href="URI" rel="">e <form method="post">por exemplo. Em JSON não é possível, a menos que você usá-lo de uma forma ad hoc, porque JSON não define nada sobre hipermídia (alguns exemplo de ad-hoc uso de hipermídia em JSON: _link : [ ... ], links : [ ... ] , _link_ : [ ... ], etc.) (PS: grande resposta)
AilurusFulgens
@AilurusFulgens, claro, eu deveria ter sido mais específico. eu quis dizer algo como "hal + json" (ou qualquer outro formato de hipermídia baseado em JSON) - a questão é a mesma: por que é bom retornar um "documento" em HTML com todos os dados, mas não fazer o mesmo em um formato hipermídia baseado em JSON?
Jonah
obrigado pela edição. para garantir que eu o entenda, se você retornou todos os resultados em uma tabela HTML, em vez de dizer um <ul>dos links clicáveis, estaria comprometendo o dimensionamento tanto quanto se fizesse o equivalente em uma resposta hal + json? especificamente, essa resposta não seria tão boa porque os resultados retornados, que presumivelmente mudam com frequência, não serão aceitáveis? considerando que uma lista de links tem menos dados, então a parte inacessível é menor? é essa a ideia ou falta mais?
Jonah