2010-12-10 12 views
9

Estoy trabajando en una API privada para nuestro back-end.
Tengo colecciones que tienen asociaciones.
Cada colección puede ser solicitada, paginada, también puede solicitar las asociaciones y paginar estas asociaciones.Diseño de URL para una API

No estamos seguros acerca de qué diseño de URL para usar ... estamos pensando en:

  • /users.json?per_page=10 & asociación = partes, audiciones & parts_per_page = 5 & auditions_per_page = 5

  • /users.json?per_page=10 & asociación [] = partes & asociación [] = audiciones & parts_per_page = 5 & auditions_per_page = 10

  • /users.json?per_page=10 & asociación [audiciones] = true & asociación [partes] [per_page] = 5

¿Qué le parece? ¿Cuál elegirías? por qué ? ¿Uno de estos no parece ser un esquema de URL válido?

Gracias!

Respuesta

14

Mi respuesta: /users.json. HTTP está optimizado para transferencias hipermediales de gran escala; el almacenamiento en caché es una gran parte de esto, y ninguno de los esquemas URI dados anteriormente son muy amigables con el caché.

Squid, por ejemplo, es una caché HTTP popular que de forma predeterminada no guardará en caché ninguna URL que tenga una cadena de consulta. Además, muchos clientes e incluso servidores e intermediarios generan y consumen parámetros de cadena de consulta en un orden indefinido; es decir, "? a = 3 & b = 5" se puede reescribir arbitrariamente como "? b = 5 & a = 3". Sin embargo, para el almacenamiento en caché HTTP, el orden es importante, y las dos páginas se almacenarán en caché por separado aunque tengan el mismo contenido. A medida que agrega parámetros, este problema aumenta exponencialmente.

Usted debe diseñar sus recursos (y sus representaciones) para tomar ventaja de almacenamiento en caché por dos en contra, pero las técnicas complementarias:

  1. Combinar representaciones fragmentadas y parciales en, representaciones más grandes unificadas, y
  2. independiente grande , representaciones unificadas en representaciones más pequeñas a lo largo de los límites del caché (que tienden a ser límites transaccionales), pero relacionadas por hipervínculos.

En su caso, el paso 1 implica la combinación de asociaciones y partes en la representación de "usuarios", sin ninguna opción para que el cliente configure cuáles y cuántos. Esto le permitirá almacenar en caché agresivamente la representación de una única respuesta sin sobrecargar su caché (y la suya) con una explosión combinatoria de respuestas debido a todas las opciones de cadena de consulta.

El paso 2 implica separar /users.json en entidades de "usuario" separadas, cada una con un recurso "asociaciones" y un recurso "partes". Por lo tanto, /users/{id} y /users/{id}/associations y /users/{id}/parts. El recurso "/ users" luego devuelve una matriz de hipervínculos a los recursos individuales "/ users/{id}", y cada representación "/ users/{id}` contiene hipervínculos a sus asociaciones y partes (esa parte es más maleable- -puede ajustarse mejor a su aplicación para integrar directamente las asociaciones y partes en el recurso del usuario). Esto le permitirá almacenar en caché agresivamente la respuesta para cada recurso "en demanda" sin tener que almacenar en caché toda su base de datos.

Luego su los usuarios gritarán "¡pero eso es 10 veces el tráfico de la red!" A lo que usted responde con calma, "no, eso es 1/10 parte del tráfico de la red, porque 9 de cada 10 recursos ya están instalados en su lado del cliente (navegador) caché (y cuando no lo son, es 1/10 parte de los recursos computacionales del servidor, ya que están ubicados en un caché del lado del servidor, y cuando tampoco están allí, evitamos estampar el ingenio h un caché inteligente en el servidor). "

Por supuesto, si el recurso /users es algo que un millón de nuevos visitantes golpean todos los días, entonces su ruta de optimización podría ser diferente. Pero no parece tan basado en sus esquemas de URI de ejemplo.

+0

Hey fumanchu, gracias por la respuesta! No entiendo por qué mis URL no están optimizadas para el caché? estas llamadas no se realizarán en un navegador, sino en el servidor (puedo guardar fácilmente en caché en función de url + params). No quiero separar las llamadas para cada asociación (es por eso que mi API no es totalmente tranquila), significaría hacer varias llamadas para obtener información y ni siquiera con el caché ... – Mike

+0

Agregué mi respuesta en el interior mi respuesta anterior (en cursiva). – fumanchu

+0

¡Gracias por la ayuda! buenos argumentos, me convences =) – Mike

3
+0

Hola, Marcus, gracias por el seguimiento y por etiquetarlo a restful-url, no encontré ninguna publicación útil sobre el uso de matrices en una API. Y no estoy seguro de que esta API se pueda categorizar como una tranquila, no queremos anidar todo ... de lo contrario, para obtener 2 asociaciones de una colección tendremos que hacer 2 llamadas y realmente no queremos ese. – Mike

1

Me gustaría ir a la primera uno. No me gusta ver la notación [] en la url, en mi humilde opinión hace que sea más difícil para el cliente usarla y comprenderla. Algunos cambios como sugerencias.

1) Como asociación parece ser un array, el cambio de las asociaciones (en plural, si tengo razón y es un array)

2) También puede tratar de poner un per_page defecto y uno opcional, incluso agregando, algo así como per_page_parts_auditions en lugar de usar tanto per_page_parts como per_page_auditions. No lo haría si su API se diseñó para ser pública, ya que hace que sea más fácil de usar pero más difícil de entender, pero como la publicó es privada ... debería ser una buena forma de evitar la replicación.

+0

1/de acuerdo (es una colección de colecciones ... básicamente relaciones sql) 2/ya hay una página por defecto (no es necesario definirla pero puede - también hay {asociación} _per_page por defecto Solo quería mostrarle algunas casos de uso) y realmente no puedo usar una_part_particiones_de_pagina, ya que solo te muestro 2 asociaciones, pero de hecho hay mucho más y tengo toneladas de diferentes colecciones (todas con diferentes asociaciones). Nuestros argumentos de {association} _per_page se generan dinámicamente. – Mike

+0

Como sus {association} _per_page argumentos se generan dinámicamente, ¿no puede hacer que {association} _per_page y en su código llame a {association} _per_code codes? –

+0

Disculpa, no recibo esta última pregunta, ya estoy pidiendo {association} _per_page .. – Mike

Cuestiones relacionadas