Diseño de reposo: llamadas múltiples versus devolución de todos los datos en una llamada

7

Estoy intentando crear una API de descanso para una aplicación de Android. Supongamos que tengo una tabla users con (id, name, email) y una tabla songs con (id, song_name, album) y una asociación de unión rica entre ellas como streams que tiene (user_id, song_id, listen_count) . Quiero obtener detalles sobre todas las transmisiones y mostrarlas en la aplicación como una lista. La lista mostrará el nombre de la canción, el nombre del álbum, el nombre de usuario y el número de escuchas. Veo tres opciones plausibles -

  1. GET a /streams y obtenga una lista de todos los song_ids y user_ids . Luego haga GET a /user/:id y /song/:id para cada usuario y la identificación de la canción para obtener la información del usuario y la canción.
  2. GET a /streams y obtenga una lista de todos los user_ids y song_ids . Luego, un GET a /user?ids=<comma_separated_ids> para obtener información sobre todos los usuarios y un GET a song?ids=<comma_separated_ids> para obtener información sobre todas las canciones.
  3. GET a /streams y recupera todo en una llamada. Algo así como -

    [
    
      {
    
        "user_id" : 10,
        "song_id" : 14,
        "listen_count" : 5,
        "user" : {
          "id"     : 10,
          "name"   : "bla", 
          "email"  : "bla",
        },
        "song" : {
          "id"     : 14,
          "name"   : "blu",
          "album"  : "blu"
       }
      },
    ...
    ]
    

Tengo la tentación de optar por la opción 3 porque me da todo en una llamada, pero no creo que esté muy tranquilo y me temo que no será escalable. La opción 2 es buena, pero se necesitan 3 llamadas, lo que significaría un tiempo considerable para cargar la lista. Y la opción 1 sigue al resto pero tomará numerosas llamadas para mostrar la lista y hacer tantas llamadas desde un dispositivo móvil no es factible.

¿Cuál sería la forma recomendada de hacer esto?

    
pregunta aandis 28.08.2015 - 08:22

2 respuestas

6

Al crear una interfaz REST, no hay ningún requisito, ni siquiera se espera, que las respuestas en la interfaz REST se correspondan directamente con las tablas o las combinaciones en la base de datos.

Su interfaz /streams puede ser representada tan fácilmente como

[
  {
    "listen_count" : 5,
    "user" : {
      "href"     : "/users/10",
      "name"   : "bla", 
    },
    "song" : {
      "href"     : "/songs/14",
      "name"   : "blu",
      "album"  : "blu"
    }
  },
  ...
]

Donde los objetos JSON contienen los detalles principales de los usuarios y las canciones que son (casi) siempre relevantes para los consumidores de un recurso de transmisión, y un enlace a los recursos de usuario / canción relevantes si se necesitan más detalles.

Esto es esencialmente una variación de su tercera opción, con un cambio a la opción 1 si se necesitan más detalles.

    
respondido por el Bart van Ingen Schenau 28.08.2015 - 09:06
3

Definitivamente, quieres una única operación GET que devuelva metadatos sobre cada canción y usuario, además de sus identificadores opacos.

  • Como usted señaló, es mucho más simple. Eso es algo bueno.
  • Hacer que una de las operaciones más comunes para las aplicaciones de sus clientes sea una única solicitud de servidor en lugar de O (n), es mucho más escalable. A la larga, la red será su mayor cuello de botella, por lo que no desea enviar más solicitudes de las que debe.
  • Los ID por sí mismos son un poco inútiles, excepto para hacer llamadas REST adicionales.
  • Siempre que sus metadatos tengan un tamaño relativamente pequeño y acotado (por ejemplo, no haya páginas de texto descriptivo o archivos de audio reales, solo nombres, tipos, conteos, etc.) que devuelvan, además de los identificadores, es probable que sea un rendimiento problema.
respondido por el Ixrec 28.08.2015 - 09:00

Lea otras preguntas en las etiquetas