Varios conceptos relacionados con REST entran en conflicto en mi cabeza cuando intento implementarlo.
Tengo un sistema de API de fondo REST-ful que contiene la lógica empresarial y una aplicación web que proporciona la interfaz de usuario. De varios recursos sobre REST (particularmente, REST en la práctica: hipermedia y arquitectura de sistemas ) sé que no debo exponer los identificadores sin formato de mis entidades, sino más bien devolver hipervínculos con rel="self"
.
Considera el ejemplo. La API REST tiene un recurso que devuelve una persona:
<Person>
<Links>
<Link rel="self" href="http://my.rest.api/api/person/1234"/>
</Links>
<Pets>
<Link rel="pet" href="http://my.rest.api/api/pet/678"/>
</Pets>
</Person>
El problema surge con la aplicación web. Supongamos que devuelve una página que contiene un hipervínculo a los navegadores:
<body class="person">
<p>
<a href="http://my.web.app/pet/???????" />
</p>
</body>
¿Qué debo poner en el href
atributo? ¿Cómo mantengo la URL de la entidad API en la aplicación web para poder obtener la entidad cuando un usuario abre la página de destino?
Los requisitos parecen contradictorios:
- El hipervínculo
href
debe conducir a la aplicación web porque es el sistema que aloja la IU - El
href
debe tener algún Identificación de la entidad debido a la aplicación web debe ser capaz de hacer frente a la entidad cuando se abre la página de destino - La aplicación web no debe analizar / construir URL REST porque no es REST-ful, dice el libro mencionado
Los URI deben ser opacos para los consumidores. Solo el emisor del URI sabe cómo interpretarlo y asignarlo a un recurso.
Por lo tanto, no puedo simplemente tomar 1234
la URL de respuesta de la API porque, como cliente RESTful, debería tratarla como si fuera algo así http://my.rest.api/api/AGRIDd~ryPQZ^$RjEL0j
. Por otro lado, debo dar alguna URL que conduzca a mi aplicación web y sea suficiente para que la aplicación de alguna manera restaure la URL original de la API y use esa URL para acceder a los recursos de la API.
Probablemente, la forma más sencilla es usar las URL de los recursos de la API como identificadores de cadena. Pero las URL de las páginas web http://my.web.app/person/http%3A%2F%2Fmy.rest.api%2Fapi%2Fperson%2F1234
son feas.
Todo parece bastante fácil para una aplicación de escritorio o una aplicación de JavaScript de una sola página. Como viven continuamente, solo pueden mantener las URL en la memoria junto con los objetos de servicio durante la vida útil de la aplicación y usarlas cuando sea necesario.
Con una aplicación web puedo imaginar varios enfoques, pero todos parecen extraños:
- Reemplace el host en las URL de API y mantenga solo el resultado. La gran desventaja es que requiere que la aplicación web maneje cualquier URL que genere la API, lo que significa un acoplamiento monstruoso. Además, no es RESTful nuevamente, porque mi aplicación web comienza a interpretar las URL.
- Exponga los identificadores sin procesar en la API REST junto con los enlaces, úselos para construir las URL de la aplicación web y luego use los identificadores en el servidor de la aplicación web para encontrar los recursos necesarios en la API. Esto es mejor, pero afectará el rendimiento del servidor de la aplicación web porque la aplicación web tendrá que pasar por la navegación del servicio REST emitiendo una cadena de solicitudes get-by-id de alguna forma para manejar cualquier solicitud de un navegador. Para un recurso algo anidado, esto puede ser costoso.
- Almacene todas las
self
URL devueltas por la API en una asignación persistente (DB?) En el servidor de aplicaciones web. Genere algunos identificadores para ellos, use los identificadores para crear las URL de la página de la aplicación web y obtener las URL de los recursos del servicio REST. Es decir, mantengo lahttp://my.rest.api/pet/678
URL en algún lugar con una nueva clave, digamos3
, y genero la URL de la página web comohttp://my.web.app/pet/3
. Esto parece una implementación de caché HTTP de algún tipo. No sé por qué, pero me parece extraño.
¿O significa que las API RESTful no pueden servir como backends para aplicaciones web?