Existe una ambigüedad conceptual sutil cuando la gente dice "URI relativo".
Según la definición de RFC3986 , un URI genérico contiene:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
Lo complicado es que, cuando se omiten el esquema y la autoridad, la parte de la "ruta" en sí misma puede ser una ruta absoluta (comienza con /
) o una ruta relativa "sin raíces". Ejemplos:
- Un URI absoluto o un URI completo:
"http://example.com:8042/over/there?name=ferret"
- Y este es un uri relativo, con ruta absoluta :
/over/there
- Y este es un uri relativo, con ruta relativa :
here
o ./here
o ../here
o etc.
Entonces, si la pregunta era "si un servidor debería producir una ruta relativa en una respuesta tranquila", la respuesta es "No" y la razón detallada está disponible aquí . Creo que la mayoría de las personas (incluyéndome a mí) en contra de "URI relativo" están en realidad en contra de "ruta relativa".
Y en la práctica, la mayoría de los marcos MVC del lado del servidor pueden generar fácilmente un URI relativo con una ruta absoluta como /absolute/path/to/the/controller
, y la pregunta es "si la implementación del servidor debe anteponer un prefijo a scheme://hostname:port
la ruta absoluta". Como la pregunta del OP. No estoy muy seguro de este.
Por un lado, sigo pensando que se recomienda que el servidor devuelva un uri completo. Sin embargo, el servidor nuncahostname:port
debería codificar lo que está dentro del código fuente como este (de lo contrario, preferiría recurrir a un uri relativo con una ruta absoluta). La solución es que el lado del servidor siempre obtenga ese prefijo del encabezado "Host" de la solicitud HTTP. Sin embargo, no estoy seguro de si esto funciona para todas las situaciones.
Por otro lado, no parece muy problemático para el cliente concatenar el http://example.com:8042
y la ruta absoluta. Después de todo, el cliente ya conoce ese esquema y el nombre de dominio cuando envía la solicitud al servidor, ¿verdad?
Con todo, yo diría que recomiendo usar un URI absoluto, posiblemente un retroceso al URI relativo con una ruta absoluta, nunca use una ruta relativa .
Depende de quién esté escribiendo el código del cliente. Si está escribiendo el cliente y el servidor, no hay mucha diferencia. O sufrirá el dolor de construir las URL en el cliente o en el servidor.
Sin embargo, si está construyendo el servidor y espera que otras personas escriban el código del cliente, entonces lo amarán mucho más si proporciona URI completos. Resolver URI relativos puede ser un poco complicado. En primer lugar, la forma de resolverlos depende del tipo de medio devuelto. Html tiene la etiqueta base, Xml puede tener xml: etiquetas base en cada elemento anidado, los feeds Atom pueden tener una base en el feed y una base diferente en el contenido. Si no le proporciona a su cliente información explícita sobre el URI base, entonces debe obtener el URI base del URI de la solicitud, ¡o tal vez del encabezado Content-Location! Y cuidado con la barra al final. El URI base se determina ignorando todos los caracteres a la derecha de la última barra. Esto significa que la barra inclinada final es ahora muy significativa al resolver URI relativos.
El único otro problema que requiere una pequeña mención es el tamaño del documento. Si devuelve una lista grande de elementos donde cada elemento puede tener varios enlaces, el uso de URL absolutas puede agregar una cantidad significativa de bytes a su entidad si no comprime la entidad. Este es un problema de rendimiento y debe decidir si es significativo caso por caso.
fuente
La única diferencia real parecería ser que es más fácil para los clientes consumir URI absolutos en lugar de tener que construirlos a partir de la versión relativa. Por supuesto, esa diferencia sería suficiente para influir en mí para hacer la versión absoluta.
fuente
A medida que su aplicación se amplía, es posible que desee realizar un equilibrio de carga, una conmutación por error, etc. Si devuelve URI absolutos, las aplicaciones del lado del cliente seguirán su configuración de servidores en evolución.
fuente
/xxx/yyy...
) y no como un URI totalmente calificado (por ejemplohttp://api.example.com/xxx/yyy...
).Usando la tricotomía de RayLou mi organización ha optado por favorecer (2). La razón principal es evitar los ataques XSS (Cross-Site Scripting). El problema es que, si un atacante puede inyectar su propia raíz URL en la respuesta que proviene del servidor, las solicitudes de usuario posteriores (como una solicitud de autenticación con nombre de usuario y contraseña) se pueden reenviar al propio servidor del atacante *.
Algunos han planteado el problema de poder redirigir las solicitudes a otros servidores para el equilibrio de carga, pero (aunque esa no es mi área de especialización) apostaría a que hay mejores formas de habilitar el equilibrio de carga sin tener que redirigir explícitamente a los clientes a diferentes Hospedadores.
* Por favor, avíseme si hay algún defecto en esta línea de razonamiento. El objetivo, por supuesto, no es prevenir todos los ataques, sino al menos una vía de ataque.
fuente
Siempre debes usar la URL completa. Actúa como el identificador único para el recurso ya que todas las URL deben ser únicas.
También diría que debes ser coherente. Dado que el encabezado HTTP de ubicación espera una URL completa basada en la especificación HTTP, la URL completa se envía de vuelta en el encabezado de ubicación al cliente cuando se crea un nuevo recurso. Sería extraño que proporcionaras una URL completa en el encabezado de la ubicación y luego las URI relativas en los enlaces dentro del cuerpo de tu respuesta.
fuente
Location
encabezado de : un URI absoluto que no contiene el esquema de URI o la ubicación de red del servidor. Si bien los enlaces y los ID a menudo se combinan, no son lo mismo: el primero tiene contexto, el segundo no.Una consideración importante en los resultados de API grandes es la sobrecarga de red adicional de incluir el URI completo repetidamente. Lo crea o no, gzip no resuelve por completo este problema (no estoy seguro de por qué). Nos sorprendió la cantidad de espacio que ocupaba el URI completo cuando había cientos de enlaces incluidos en un resultado.
fuente
Un inconveniente de usar URI absolutos es que la API no se puede usar como proxy.Retirarlo ... no es cierto. Debería buscar una URL completa que incluya el dominio.
fuente
En cuanto a los pros, veo la reducción de bytes a transmitir a expensas del manejo adicional requerido por un cliente para la ruta (absoluta). Si está desesperado por guardar cada byte, incluso después de probar la codificación de contenido como gzip, el uso adecuado de los encabezados de almacenamiento en caché, el uso de etags y solicitudes condicionales en el cliente, entonces esto puede ser necesario al final, pero espero rendimientos mucho más altos en sus otros esfuerzos fueron.
Respecto a los contras, veo una pérdida de control sobre cómo se puede dirigir el flujo de clientes entre recursos en el futuro (balanceo de carga, pruebas A / B, ...), y lo consideraría una mala práctica en cuanto a la gestión de una web. API. La URL que proporciona ya no es básicamente opaca para el cliente (consulte Tim Berners-Lee Axioms of Web Architecture sobre opacidad de URI ). Al final, usted se vuelve responsable de mantener contentos a los clientes con respecto al uso creativo de su API, incluso si solo se trata de la estructura de su espacio de URL. Si alguna vez necesita permitir una modificación de URL definida explícitamente, considere el uso de plantillas de URI como se usa en el lenguaje de aplicación de hipertexto .
fuente