Estoy en el proceso de crear una API REST y actualmente encuentro el siguiente problema:
FooEs el primer recurso. Las operaciones CRUD se pueden aplicar a través del/foo/URI.BarEs el segundo recurso. Las operaciones CRUD se pueden aplicar a través del/bar/URI.- Todos
Fooestán asociados con cero o unoBar. La razón por la que no tratoBarcomo un subrecursoFooes porque la mismaBarinstancia se puede compartir entre variosFoo. Así que pensé que es mejor acceder a él a través de un URI independiente en lugar de hacerlo/foo/[id]/bar.
Mi problema es que en una cantidad significativa de casos, los clientes que solicitan una Fooinstancia también están interesados en la Barinstancia asociada . Actualmente, esto significa que tienen que realizar dos consultas en lugar de una. Quiero presentar una forma que permita obtener ambos objetos con una sola consulta, pero no sé cómo modelar la API para hacerlo. Lo que se me ocurrió hasta ahora:
- Podría introducir un parámetro de consulta similar a esto:
/foo/[id]?include_bar=true. El problema con este enfoque es que la representación de recursos (p. Ej., La estructura JSON) de la respuesta necesitaría verse diferente (p. Ej., Un contenedor como en{ foo: ..., bar: ... }lugar de solo un serializadoFoo), lo que hace que elFoopunto final del recurso sea "heterogéneo". No creo que sea algo bueno. Al realizar consultas/foo, los clientes siempre deben obtener la misma representación de recursos (estructura), independientemente de los parámetros de consulta. - Otra idea es introducir un nuevo punto final de solo lectura, por ejemplo
/fooandbar/[foo-id]. En este caso, no es problema devolver una representación como{ foo: ..., bar: ... }, porque entonces es solo la representación "oficial" delfooandbarrecurso. Sin embargo, no sé si ese punto final auxiliar es realmente RESTful (es por eso que escribí "can" en el título de la pregunta. Por supuesto, es técnicamente posible, pero no sé si es una buena idea).
¿Qué piensas? existen algunas otras posibilidades?

Barno puede existir sin estar asociado a aFoo. Sin embargo, como escribí anteriormente, es posible que múltiplesFoocorreos compartan lo mismoBar. Debería ser posible crear unFoosin unBarasociado, por lo que no creoBarque deba tratarse como padre.Respuestas:
Una API REST de nivel 3 le devolverá un
Fooy también un enlace que indica lo relacionadoBar.Luego puede agregar una función de "profundizar" a su API que permite la navegación de enlaces;
La función de profundización se ubicaría frente a las API e interceptaría las respuestas. Haría las llamadas de profundización y completaría los detalles antes de devolver la respuesta a la persona que llama.
Esto es algo bastante común en REST de nivel 3, ya que reduce mucho el chat del cliente / servidor sobre http lento. La compañía para la que trabajo produce una API REST de nivel 3 con exactamente esta característica.
Actualización: para lo que vale, así es como podría verse en JSON. Así es como lo estructuraría nuestra API. Tenga en cuenta que puede anidar sus desgloses para extraer enlaces de enlaces, etc.
fuente
linksmatriz, cada entrada es un objeto de enlace con unrely unuricampo (similar a su ejemplo xml). ¿Debo agregar un tercer campo a cada objeto de enlace (por ejemplodata)? ¿Hay algún estándar?Si el 95% de todas las consultas quieren
Foo, así comoBar, a continuación, sólo tiene que devolverlo dentro delFooobjeto cuando se solicita unaFoo. Simplemente agregue una propiedadbar(o algún otro término para la relación) y coloque elBarobjeto allí. Si la relación no existe, utilice nulo.Creo que estás pensando demasiado en esto :)
fuente
Foo, y dado que cada unaBares bastante grande en la memoria (alrededor de 3x-4x del tamaño deFoo), no quiero devolver un mensajeBarsi un cliente no lo solicita explícitamente.