Muchas llamadas asincrónicas frente a una sola llamada a la API

12

Estamos desarrollando una API REST que, entre otras, será consumida por una interfaz HTML5 a través de JavaScript. La aplicación es para uso dentro de la organización y generalmente tiene alrededor de 300 usuarios, pero queremos escalar bien hasta 1000 usuarios más o menos.

Normalmente, las conexiones a la API se realizarán dentro de la LAN, por lo que la calidad y la latencia de la conexión serán buenas, aunque no se excluye el uso ocasional en Internet, donde las conexiones podrían ser más lentas y con más retraso a través de 3G / 4G.

Las dos opciones que pensamos son:

  1. El frontend realizará varias llamadas asincrónicas simultáneas a la API para cargar los diversos componentes de la interfaz.

    • Pros: simplicidad.
    • Contras: Más conexiones al servidor.
  2. El controlador de la interfaz hará una sola llamada a la API pasando como parámetros qué objetos deben recuperarse.

    • Pros: solo una conexión al servidor, aunque el servidor hará varias conexiones a la base de datos.
    • Contras: Requiere mecanismos tanto en frontend como en API. Se complica el diseño.

Explicaciones adicionales: Habrá diferentes recursos ... / Producto ... / Ubicaciones, etc. Estos recursos podrían recuperarse solos, pero habrá otro recurso abstracto ... / pantalla? Producto y ubicaciones que obtendrán ambos en una sola llamada.

mattinsalto
fuente

Respuestas:

14

La opción 1 (llamadas asíncronas múltiples) es la mejor opción porque:

  1. cada llamada individual es su propia entidad , por lo que puede volver a intentarlo individualmente si algo falla. En la arquitectura monolítica de 'una llamada', si una cosa falla, debe volver a hacer toda la llamada
  2. el código del lado del servidor será más simple: nuevamente, modularidad , lo que significa que diferentes desarrolladores pueden trabajar en diferentes recursos de API
  3. En un patrón MVC típico , no tiene sentido que una llamada API cargue múltiples recursos separados ; por ejemplo, si solicita /productsobtener una lista de productos para mostrar en una página, y también desea mostrar una lista de ubicaciones donde se venden productos populares, tiene dos recursos separados: Producty Location. Aunque se muestran en la misma página, lógicamente no puede hacer una llamada /productsy hacer que también devuelva ubicaciones
  4. sus informes de registro / utilización serán más simples en el enfoque modular. Si realiza una solicitud /productsy también está cargando ubicaciones, sus archivos de registro serán realmente confusos
  5. Si tiene un problema con un recurso en particular, el enfoque de una sola llamada hará que se rompa toda la página y no será obvio para los usuarios lo que se rompió , y esto significa que su equipo tardará más en solucionar el problema; sin embargo, en el enfoque modular, si una cosa se rompe, será muy obvio lo que se rompió y puede solucionarlo más rápido. Tampoco arruinará el resto de la página (a menos que las cosas estén demasiado unidas ...)
  6. será más fácil hacer cambios en general si las cosas están separadas; Si tiene 5 recursos cargados por una llamada API, será más difícil descubrir cómo no romper las cosas cuando desea cambiar algo

El punto es que los recursos están separados, y en una API REST devolver muchos recursos separados de una sola ruta de API no tiene sentido, incluso si está "guardando conexiones al servidor". Por cierto, el uso de parámetros para cargar condicionalmente (diferentes) recursos no es RESTful.

Dicho todo esto, la única opción lógica es hacer múltiples solicitudes asíncronas para separar recursos: ¡ tome el enfoque modular !

PD: no optimice prematuramente las "conexiones al servidor", especialmente cuando las conexiones HTTP tienen una sobrecarga increíblemente baja y está en una LAN. Ese tipo de pensamiento en lugar de elegir el diseño más simple desde el principio te meterá en problemas más adelante.

Chris Cirefice
fuente
1
Además, el modular es probablemente más fácil de realizar pruebas unitarias.
user949300
@ user949300 Buen punto, ¡ni siquiera pensé en eso! De hecho, las pruebas unitarias serían mucho más fáciles si las cosas se desacoplan.
Chris Cirefice
Gracias por la respuesta rápida y extendida. Estoy de acuerdo con todo, pero creo que no lo expliqué bien. Habrá diferentes recursos / Producto / Ubicaciones, etc. Estos recursos podrían recuperarse solos, pero habrá otro recurso / pantalla abstracto: Producto y Ubicaciones que obtendrán ambos en una sola llamada. De todos modos, también prefiero la forma más simple.
mattinsalto
@mattinsalto El enfoque de /screen?Product&Locationses un mal enfoque, al menos con toda la experiencia que tengo desarrollando API REST y una aplicación web que los utilizó. Desde una perspectiva monolítica pura (por ejemplo, en Ruby on Rails), tener una ruta /screenque cargue ambos Producty Locationrecursos está perfectamente bien. Sin embargo, desde una perspectiva REST , nunca querrás que una ruta cargue más de una (a menos que estés uniendo tablas para obtener más datos a la vez). Lo que /screendebe hacer es cargar una página básica diseño y AJAX su API para obtener los datos ( Product, Location, etc.).
Chris Cirefice
@mattinsalto Si está desarrollando una API REST para usar en una aplicación web (así como otras cosas), solo necesita enfocarse en los datos y menos en cómo sus aplicaciones los usarán. La API REST debe admitir operaciones básicas (según las necesite) para cada recurso. Entonces, su aplicación web va a hacer la carga de todos los recursos que necesita para cualquier página determinada (por ejemplo, /screense Ajax HTTP GETa /products/populare /locations). Su API no debería ser la que realiza múltiples cargas, porque es poco probable que muestre los datos de la misma manera en una aplicación web frente a Android, por ejemplo.
Chris Cirefice