Muchas solicitudes pequeñas frente a pocas solicitudes grandes (diseño de API)

49

Actualmente estoy trabajando en un proyecto con una organización de la siguiente manera:

  • Cliente : obtiene datos del servidor principal a través de la API REST.
  • Servidor : solicita datos de otros servidores a través de API de terceros
  • API de terceros : servicios fuera de mi control que proporcionan datos al servidor (Reddit, Hackernews, Quora, etc.)

En aras de la discusión, supongamos que el cliente primero necesita una lista de elementos de cada una de las API de terceros. De esta lista, se elegirá un elemento en el que el cliente necesita ver el contenido completo del elemento, así como las respuestas (es decir, comentarios) al elemento. Estoy tratando de decidir entre tres opciones:

A la carta

En este enfoque, tendría 3 puntos finales separados en mi servidor: uno para obtener la lista de elementos, uno para obtener el contenido principal de un elemento y otro para obtener las respuestas del elemento.

  • Pros: nunca hago más solicitudes de las que necesito, las solicitudes deben ser pequeñas, por lo que generalmente deben ser más rápidas.
  • Contras: Tengo que hacer muchas solicitudes. Después de elegir un elemento de la lista, el usuario puede tener que esperar antes de ver el contenido principal y luego esperar aún más para ver las respuestas

Caché del lado del servidor

En esta solicitud, haría una sola llamada a mi servidor para "buscar" todos los datos de todas las fuentes. Los datos se almacenarían en caché en el servidor. El cliente tendría los mismos puntos finales REST que antes, excepto que no habría mucha espera entre llamadas ya que mi servidor ya tiene los datos y solo tiene que alimentarlos al cliente.

  • Pros: sigue siendo fácil de implementar en el lado del cliente, pero sin los problemas de latencia
  • Contras: Un poco más complicado en el lado del servidor, y la primera llamada podría tomar mucho, mucho tiempo.

Caché del lado del cliente

Este escenario es similar al anterior, excepto que el cliente solo hace una solicitud al servidor: dame todos los datos. A partir de aquí, es responsabilidad del cliente guardar los datos y usarlos adecuadamente.

  • Pros: fácil implementación del servidor, muy rápida después de la primera llamada
  • Contras: la primera llamada será muy lenta, la implementación más complicada del lado del cliente

No estoy seguro de cuál es el mejor enfoque, o si tal vez me estoy perdiendo la solución obvia. Cualquier consejo sería muy apreciado!

williamg
fuente
Esto me parece una elección entre frescura y velocidad. ¿Qué prefieren sus grupos de interés y usuarios finales?
Erk

Respuestas:

28

Una cosa a tener en cuenta es la latencia de red esperada (es decir, el tiempo de ping) entre sus clientes y su servidor. En una situación de alta latencia con un ancho de banda bueno, muchas solicitudes pequeñas funcionarán significativamente peor que una grande.

Recientemente he estado colaborando en un proyecto de aplicación web respaldado por bases de datos de varios equipos en el que uno de los equipos está en India (el resto está en los EE. UU.). Tenemos una única instancia de base de datos alojada en nuestra oficina de EE. UU. A la cual los desarrolladores conectan nuestras instancias locales de servidores web. Mi escritorio está a unos cincuenta pies y dos saltos de LAN lejos de la instancia de la base de datos, y el rendimiento está bien.

Cuando comenzamos a trabajar con los desarrolladores en India, estaban experimentando enormes tiempos de espera al iniciar la aplicación y navegar de página en página. Estamos hablando de tiempos de espera de diez minutos aquí. Resulta que esto se debió a que el tiempo de ping de ~ 200 ms desde sus escritorios a nuestro servidor de base de datos de desarrollo se multiplicaba por muchas, muchas breves consultas a la base de datos. Mi ping local de 0.5 ms fue tan trivial que la conversación entre el servidor web y el servidor de base de datos nunca importó. Esta fue la primera vez que tuvimos una separación geográfica entre el servidor web y el servidor de bases de datos.

La solución en nuestro caso fue clonar el servidor de la base de datos y respaldar la copia en India, pero el punto aquí es tener en cuenta que si su cliente y servidor están muy separados, la latencia de la red se multiplicará por el número de comunicaciones a través de cable. El ancho de banda una vez que se establece la conexión suele ser mucho menos preocupante.

JakeRobb
fuente
2

Estas tres opciones no son mutuamente excluyentes, puede usar una combinación de cachés del lado del cliente y del lado del servidor. Sin embargo, algunos datos, como los comentarios, pueden volverse obsoletos si se guardan en la memoria caché durante demasiado tiempo. Teniendo en cuenta que no puede verificar si ese es el caso, probablemente debería abstenerse de almacenarlo. Por otro lado, el contenido generalmente no cambia drásticamente, por lo que no sería perjudicial almacenarlo en caché en el lado del servidor y luego buscarlo previamente en el lado del cliente para reducir la latencia.

wfdctrl
fuente
1

Basado solo en la información que proporcionó, opción 1, porque

  • con una sola solicitud del cliente, estaría mezclando manzanas y naranjas y la canasta de frutas podría ser muy grande.

  • el almacenamiento en caché es una compensación en la que gana rendimiento pero potencialmente pierde consistencia (datos obsoletos). Si no tiene ningún problema de rendimiento identificado, no vale la pena arriesgarse con los problemas de sincronización.

guillaume31
fuente
0

Siempre he encontrado algunas solicitudes grandes para tener un mejor rendimiento y ser más escalables. Pero hay compensaciones en todos los enfoques, por lo que depende de las necesidades del servidor y el cliente. Es posible que desee utilizar otra opción, que es hacer que el cliente especifique un rango completo o un conjunto de datos para recuperar, no necesariamente todos los datos, sino un rango que se ajusta con el tiempo para que coincida con el ancho de banda disponible.

Frank Hileman
fuente
0

Yo (casi) descontaría la opción 3. Elegir entre 1 y 2 depende de dos cosas:

  • (A) qué tan grande es el resultado de una sola búsqueda total
  • (B) cuánto de los detalles del resultado el cliente / usuario usará típicamente en esa sesión.

Es fácil tomar una decisión si A y B son extremos:

  • Si A es grande y B es pequeño, definitivamente vaya a la opción 1 (a la carta).
  • Si A es pequeño y B es grande, elija 2 (caché del lado del servidor) o incluso 3 (caché del lado del cliente).

Para cualquier otra variación A / B (grande / pequeña), deberá aplicar su criterio. Yo a menudo proporcionan ambos extremos gruesos y finos para atender a los diferentes casos de uso de distintos clientes.

Cornel Masson
fuente
0

Como siempre en programación, depende.

Entonces, la verdadera pregunta es: ¿qué debe considerar al decidir por A / B / C o una combinación de los tres?

Diría que los factores de discriminación reales son los detalles de implementación de las API de terceros que está consumiendo. Como ejemplo, debe considerar: ¿son rápidos o lentos? ¿Los datos cambian con frecuencia e inesperadamente? ¿Son "habladores" o descansan?

En el caso de servicios rápidos y fáciles de llamar, con datos que cambian con tanta frecuencia que el caché del lado del servidor creará problemas de caché obsoleto, vaya por todos los medios a la opción 1: más solicitudes, sin caché, solo cuando sea necesario.

Si sus datos externos van a cambiar de una manera predecible, o está limitado con el uso, o simplemente puede obtener una mejor experiencia de usuario almacenando datos en caché en su servidor, vaya con 2. Pero tenga en cuenta que el caché no está libre: tiene costos en términos de depuración y, a veces, los usuarios se quejan de que no ven las actualizaciones.

Opción 3, consideraría solo si los datos no son muchos, pero en ese caso incluso las opciones 1 o 2 pueden funcionar, y usted mantiene más lógica en el servidor, por lo que me quedaría con 1 o 2.

Solo mi 2c.

A. Chiesa
fuente