Muitas chamadas assíncronas versus uma única chamada para a API

12

Estamos desenvolvendo uma API REST que, entre outras, será consumida por um front-end HTML5 via javascript. O aplicativo é para uso dentro da organização e geralmente possui cerca de 300 usuários, mas queremos escalar bem até 1000 usuários.

Normalmente, as conexões com a API serão feitas na LAN, para que a qualidade e a latência da conexão sejam boas, embora não seja excluído o uso ocasional na Internet, onde as conexões podem ser mais lentas e com mais atraso via 3G / 4G.

As duas opções que pensamos são:

  1. O front-end fará várias chamadas assíncronas simultâneas para a API para carregar os vários componentes da interface.

    • Prós: Simplicidade.
    • Contras: Mais conexões com o servidor.
  2. O controlador do front-end fará uma única chamada para a API passando como parâmetros que objetos precisam ser buscados.

    • Prós: Apenas uma conexão com o servidor, embora o servidor faça várias conexões com o banco de dados.
    • Contras: requer mecanismos no frontend e na API. Isso complica o design.

Explicações adicionais: Haverá recursos diferentes ... / Produto ... / Locais etc. Esses recursos podem ser buscados sozinhos, mas haverá outro recurso abstrato ... / tela? Produto e Locais que buscarão os dois em uma chamada.

mattinsalto
fonte

Respostas:

13

A opção 1 (várias chamadas assíncronas) é a melhor opção porque:

  1. cada chamada individual é sua própria entidade , para que você possa tentar novamente individualmente se algo falhar. Na arquitetura monolítica de "chamada única", se uma coisa falhar, você deverá fazer a chamada inteira novamente
  2. o código do lado do servidor será mais simples: novamente, modularidade , o que significa que diferentes desenvolvedores podem trabalhar em diferentes recursos da API
  3. Em um padrão típico do MVC , não faz sentido que uma chamada de API carregue vários recursos separados ; por exemplo, se você solicitar /productsuma lista de produtos para exibir em uma página e também desejar exibir uma lista de locais onde os produtos populares são vendidos, você terá dois recursos separados: Producte Location. Embora eles sejam exibidos na mesma página, você não pode fazer uma chamada lógica para /productse também devolver os locais.
  4. seus relatórios de registro / utilização serão mais simples na abordagem modular. Se você fizer uma solicitação /productse também estiver carregando locais, seus arquivos de log serão realmente confusos
  5. se você tiver um problema com um recurso específico, a abordagem de uma chamada fará com que a página inteira seja interrompida e não será óbvio para os usuários o que houve - e isso significa que a equipe levará mais tempo para corrigir o problema; no entanto, na abordagem modular, se uma coisa quebrar, será muito óbvio o que quebrou e você poderá corrigi-lo mais rapidamente. Também não arruinará o resto da página (a menos que as coisas estejam muito próximas ...)
  6. será mais fácil fazer alterações em geral se as coisas forem separadas; se você tiver cinco recursos sendo carregados por uma chamada de API, será mais difícil descobrir como não interromper as coisas quando você quiser alterar algo

O ponto principal é que os recursos são separados e, em uma API REST, retornar muitos recursos separados de um único caminho da API não faz sentido, mesmo se você estiver "salvando conexões com o servidor". A propósito, o uso de parâmetros para carregar condicionalmente (diferentes) recursos não é RESTful.

Tudo isso dito, a única opção lógica é fazer várias solicitações assíncronas para separar recursos: adote a abordagem modular !

PS - Não otimize prematuramente as "conexões com o servidor", principalmente quando as conexões HTTP estiverem incrivelmente baixas e você estiver em uma LAN. Esse tipo de pensamento, em vez de escolher o design mais simples logo de cara, vai causar problemas mais tarde.

Chris Cirefice
fonte
1
Além disso, o modular é provavelmente mais fácil para o teste de unidade.
user949300
@ user949300 Bom ponto, eu nem pensei nisso! De fato, o teste de unidade seria muito mais fácil se as coisas fossem dissociadas.
Chris Cirefice
Obrigado pela resposta rápida e estendida. Eu concordo com todos, mas acho que não expliquei tudo bem. Haverá recursos / produtos / locais diferentes etc. Esses recursos podem ser buscados sozinhos, mas haverá outro recurso / tela abstrata? Produto e locais que buscarão os dois em uma chamada. Enfim, eu também prefiro a maneira mais simples.
Mattinsalto
@mattinsalto A abordagem de /screen?Product&Locationsé uma abordagem ruim , pelo menos com toda a experiência que tenho desenvolvendo APIs REST e um aplicativo Web que as usou. De uma perspectiva monolítica pura (por exemplo, no Ruby on Rails), ter uma rota para /screencarregar tanto recursos Productquanto Locationrecursos é perfeitamente adequado. No entanto, da perspectiva REST , você nunca desejará que uma rota carregue mais de uma (a menos que você esteja JOINING tables para obter mais dados de uma vez). O que /screendeve fazer é carregar uma página básica de layout e você Ajax a sua API para obter os dados ( Product, Location, etc).
Chris Cirefice
@mattinsalto Se você estiver desenvolvendo uma API REST para usar em um aplicativo Web (além de outras coisas), precisará se concentrar apenas nos dados e menos em como seus aplicativos os usarão. A API REST deve suportar operações básicas (conforme necessário) para cada recurso. Em seguida, seu aplicativo Web fará o carregamento de todos os recursos necessários para qualquer página (por exemplo /screen, o AJAX será HTTP GETpara /products/populare /locations). Sua API não deve ser a responsável por vários carregamentos, porque é improvável que você exiba os dados da mesma maneira em um aplicativo Web versus Android, por exemplo.
Chris Cirefice