¿Cómo y por qué evolucionaron los marcos de aplicación web modernos para desacoplar las rutas URL del sistema de archivos?

67

En comparación con hace aproximadamente 10 años, he notado un cambio hacia marcos que usan el estilo de enrutamiento que desacopla la ruta URL del sistema de archivos. Esto generalmente se logra con la ayuda de un patrón de controlador frontal.

Es decir, cuando antes, la ruta URL se asignaba directamente al sistema de archivos y, por lo tanto, reflejaba los archivos y carpetas exactos en el disco, hoy en día, las rutas URL reales están programadas para dirigirse a clases específicas a través de la configuración y, como tal, ya no reflejan el archivo Carpeta del sistema y estructura de archivos.

Pregunta

¿Cómo y por qué esto se convirtió en algo común? ¿Cómo y por qué se decidió que es "mejor" hasta el punto en que el enfoque directo al archivo, una vez común, fue efectivamente abandonado?

Otras respuestas

Aquí hay una respuesta similar que entra un poco en el concepto de ruta y algunos beneficios y desventajas: con los marcos PHP, ¿por qué se usa el concepto de "ruta"?

Pero no aborda los aspectos del cambio histórico, o cómo o por qué este cambio se produjo gradualmente, a donde cualquier proyecto nuevo hoy en día está utilizando más o menos este nuevo patrón de estilo de enrutamiento y el directo al archivo está desactualizado o abandonado.

Además, la mayoría de esos beneficios e inconvenientes mencionados no parecen ser lo suficientemente significativos como para justificar un cambio global de este tipo. El único beneficio que puedo ver impulsando este cambio tal vez es ocultar el sistema de archivos / carpetas al usuario final, y también la falta ?param=value&param2=value, lo que hace que las URL se vean un poco más limpias. ¿Pero fueron esos el único motivo del cambio? Y si es así, ¿por qué estaban esas razones detrás de esto?

Ejemplos:

Estoy más familiarizado con los marcos PHP y muchos marcos modernos populares utilizan este enfoque de enrutamiento desacoplado. Para que funcione, configure la reescritura de URL en Apache o un servidor web similar, donde la funcionalidad de la aplicación web ya no se activa a través de una ruta URL directa a archivo.

Zend expresivo

https://docs.zendframework.com/zend-expressive/features/router/aura/
https://docs.zendframework.com/zend-expressive/features/router/fast-route/
https: //docs.zendframework. com / zend-expressive / features / router / zf2 /

Marco Zend

https://docs.zendframework.com/zend-mvc/routing/

Laravel

https://laravel.com/docs/5.5/routing

CakePHP

https://book.cakephp.org/3.0/en/development/routing.html

Dennis
fuente
14
¿hubo realmente tal cambio? ¿O tal vez la mayoría de los lenguajes / marcos nunca utilizaron el mapeo directo del sistema de archivos? ¿Quizás es solo PHP el que se está poniendo al día con el resto de los cuerdos? En mi opinión, sus observaciones son erróneas, por lo que no hay una buena respuesta. También "cambio" que mencionas ocurrió solo en el mundo PHP. pero es demasiado amplio pregunta en mi opinión ...
rsm
2
@rsm Tuve una primera reacción similar, pero pensándolo mejor, realmente es algo que se ha hecho en muchos idiomas y plataformas, lo que hace que sea una fuente muy común de vulnerabilidades.
JimmyJames
66
@rsm, esto puede ser más evidente en los frameworks PHP, pero para usar de otra manera, en un momento determinado, antes de que cualquier framework realmente se ponga de moda, ya sea ASP, .NET, PHP, JSP, etc., la web usó principalmente directamente enfoque de archivo. ¿Por qué se desarrollaron todos estos marcos para usar el enfoque desacoplado? Técnicamente, el enfoque directo al archivo todavía es factible, y estoy seguro de que los marcos modernos pueden usarlo. ¿O pueden ellos? Tal vez no pueden, y tal vez hay buenas razones de por qué no lo hacen. ¿Cuáles serían esas razones? Ni siquiera proporcionan una forma o un complemento para hacer esto, simplemente erradicaron por completo el archivo directo.
Dennis
2
¿No se trata (en parte) también de ver una URL (un localizador , cómo encontrar un recurso) como URI (e identificador )?
Hagen von Eitzen
2
Lectura relacionada de la historia antigua: los URI geniales no cambian - Tim Berners-Lee, 1998
Michael Hampton

Respuestas:

72

En su forma más básica, un sitio web sirve archivos estáticos. Mapear la ruta URL a una ruta de archivo es la opción más obvia; esencialmente, es un sitio FTP de solo lectura.

Entonces la gente quería cambiar el contenido de la página con algunas secuencias de comandos. La forma más fácil es incrustar un lenguaje de script en la página y ejecutarlo a través de un intérprete. Nuevamente, dada la ruta ya existente -> ruta de ruta de archivo, esto fue bastante simple.

Pero realmente, está ejecutando ese archivo como argumento para el intérprete ahora. Debe identificar cuándo la solicitud es para un archivo estático y cuándo es para algo que necesita interpretar.

Una vez que comience a usar lenguajes compilados más avanzados, estará aún más divorciado de la ubicación del archivo.

Además, su servidor web ya está almacenando en caché archivos estáticos y está haciendo todo tipo de optimizaciones, lo que significa que golpear el sistema de archivos es la excepción y no la regla. En este punto, la antigua ruta del sistema de archivos de enlace es más un obstáculo que una ayuda.

Pero creo que el verdadero cambio radical se produjo cuando los usuarios querían deshacerse de la extensión del archivo de la ruta. Obtener myPage.asp o myPage.php fue algo que confundió a las personas "normales" e interfirió con el SEO.

Debido a que el usuario ve la ruta, se ha convertido en parte de la interfaz de usuario de la web y, como tal, debe estar completamente libre de limitaciones técnicas. Hemos perdido el 'www' y prácticamente todo es un '.com'. Múltiples URL apuntarán a la misma página.

Si gano más dinero con mydomain.com/sale vs www.mydomain.co.uk/products/sale.aspx, entonces no quiero que haya ninguna limitación técnica que se interponga en mi camino.

Ewan
fuente
77
Siempre pensé que el deseo de ocultar extensiones de archivo era en parte "seguridad por oscuridad", lo que hacía un poco más difícil saber qué tecnología empleaba un sitio para que sea menos fácil enfocarse en explotaciones particulares conectadas / conocidas de ciertos servidores y técnicos en ese momento
Caius Jard
20
@CaiusJard es parte de eso, pero otra parte es el agnosticismo tecnológico: al haber reemplazado file.html en nuestros caminos, no queríamos quedarnos con otro interruptor más tarde (por ejemplo, file.phtml a file.php, o incluso a file.asp). Pero dado que estamos disociando la URL y la ruta del sistema de archivos (usando enrutamiento o lo que sea) para acceder a los recursos creados a partir de registros de bases de datos y / u otras fuentes, ¿por qué tener una extensión en la URL?
HorusKol
39
El agnosticismo de @HorusKol Technology no se trata solo de tener que cambiar todos los archivos en su camino. Ser capaz de cambiar las tecnologías de back-end sin romper el flujo de trabajo y los marcadores de sus clientes y sin destruir su SEO puede ser enorme .
Shane
77
Curiosamente, nunca se recomendó tener extensiones de nombre de archivo en el URI, por lo que deberían haberse desconectado del sistema de archivos desde el principio. La primera referencia que puedo encontrar para esto es de 1998 , que en realidad es anterior a la mayoría de los desarrollos descritos en esta respuesta.
Konrad Rudolph el
8
En los viejos tiempos mydomain.com/sale todavía funcionaba; se redirigió a / sale / y se cargó bien (su página era mydomain.com/sale/index.aspx pero nadie vio el index.aspx).
Joshua
39

Puede consultar un informe técnico de Roy Fielding sobre REpresentational State Transfer (REST) sobre cuándo y por qué . El primer marco que conocía que hacía la distinción entre un recurso y un archivo era Ruby on Rails, introduciendo el concepto de URL en el enrutamiento de código.

Los conceptos principales detrás de REST que fueron transformadores fueron:

  • Una URL representa un recurso
  • Ese recurso puede tener múltiples representaciones
  • La URL no debe romperse si la aplicación se reestructura
  • Las aplicaciones deben abarcar la apatridia de la web.

El principal inconveniente de que la URL sirva directamente a los archivos es que experimenta los siguientes problemas:

  • Los enlaces de recursos se rompen constantemente a medida que se reorganizan los sitios web
  • Recurso y representación están unidos

Creo que también es importante proporcionar un equilibrio justo:

  • No todos los recursos tienen la misma importancia. Es por eso que todavía tiene recursos basados ​​en estilo servidos directamente (CSS, JavaScript / EcmaScript, imágenes)
  • Hay mejoras de REST como HATEOAS que admiten mejor las aplicaciones de una sola página.
Berin Loritsch
fuente
cuando dices representación, ¿te refieres a cosas como JSON / HTML / TEXT / etc? Estoy vagamente familiarizado con REST, pero imagino que incluso con REST tienes que tener algún tipo de disparador para cambiar la representación de la respuesta ...
Dennis
@ Dennis, sí. HTTP tiene una serie de encabezados que se pueden usar para insinuar la forma deseada ( developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation ) y REST se trataba de adoptar las fortalezas de HTTP. Sin embargo, todavía no es raro que una aplicación tenga una forma patentada de negociar el contenido deseado.
Berin Loritsch
55
CGI (1993), Servlets (1997) y JSP (1999) a menudo desacoplaron las URL del sistema de archivos y son anteriores a REST (2000). Sin embargo, esta respuesta es básicamente correcta al identificar las razones de la popularidad del patrón de diseño: REST, Java Struts y Ruby on Rails tienen una gran influencia en la popularidad del siglo XXI de separar los recursos de las representaciones.
dcorking
1
Según el artículo de Fielding, "La primera edición de REST se desarrolló entre octubre de 1994 y agosto de 1995"
Connor
1
@dcorking, CGI en ese momento no desacoplaba las URL de los archivos, simplemente ejecutaba el archivo en su lugar 9 de cada 10. Los servlets podrían ser la coincidencia más cercana, pero si está hablando sobre el concepto de rutas y tener un espacio de URL diseñado , que vino con Rails y frameworks como este.
Berin Loritsch
20

No creo que sea un artefacto de los marcos de aplicaciones web modernas , es principalmente un artefacto de publicación dinámica de páginas en general.

En los viejos tiempos había páginas web en su mayoría estáticas, donde un software servía archivos individuales del sistema de archivos por su ruta. Lo hicieron principalmente porque la asignación 1: 1 de las rutas URL a las rutas del sistema de archivos (con un directorio designado como la raíz web) era la opción obvia, aunque la reescritura de URL (por ejemplo, para hacer redirecciones después de mover archivos) también era común.

Luego llegó la era de servir contenido dinámico. Los scripts CGI (y todo evolucionó a partir de ellos) crearon las páginas sobre la marcha, respaldadas por una base de datos de algún tipo. Los parámetros GET en URL se volvieron comunes, por ejemplo en.wikipedia.org/w/index.php?title=Path_(computing) .

Sin embargo, es más fácil de usar tener una URL legible que consta de solo segmentos de ruta. Entonces, las aplicaciones dinámicas mapearon rutas simples (por ejemplo, en.wikipedia.org/wiki/Path_(computing) ) a parámetros, y estas asignaciones se conocen como "rutas".

Quizás este enfoque se siente más reciente a medida que ganó popularidad cuando la importancia de la usabilidad se reconoció más ampliamente y también se convirtió en parte del SEO. Esta es probablemente la razón por la que se construyó directamente en los grandes marcos web.

Bergi
fuente
12

Una razón es que la carga de un archivo desde el disco en cada solicitud es lenta, por lo que los servidores web comenzaron a crear formas de almacenar en caché los archivos en la memoria, entonces si va a intentar mantenerlo en la memoria de todos modos, ¿por qué importa dónde estaba? ¿disco?

Una razón es que muchos marcos web están escritos en lenguajes compilados, por lo que ni siquiera tiene una estructura de archivos en el disco, solo un jararchivo o lo que sea. Los idiomas interpretados tomaron prestadas ideas que les gustaron de las compiladas.

Una razón es el deseo de rutas más semánticas y dinámicas, como https://softwareengineering.stackexchange.com/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes. Obviamente, no quieres un /var/www/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes.phparchivo. Solía ​​hacer reglas de reescritura de URL en la configuración del servidor web para crear rutas como esta. Ahora es solo un cambio de código, que es mucho más simple desde el punto de vista operativo.

Karl Bielefeldt
fuente
No necesita reescribir URL para ese ejemplo.
Yay295
1
Se maneja mediante un código que reconoce la primera parte de la ruta y utiliza el número / 363517 / para buscar la pregunta en una base de datos. Nada que ver con el servidor web en sí, sino una aplicación ...
Will Crawford
11

Una de las principales razones es probable que este enfoque de mapeo de URIs a rutas de archivos haya llevado a una gran cantidad de liberaciones accidentales de datos a través de File Path Traversal

Cuando asigna la ruta al sistema de archivos, significa que debe verificar que cada ruta que reciba como solicitud se asigne a archivos a los que los clientes deberían poder acceder. Un enfoque simple para garantizar que no suceda es eliminar el mapeo transparente y hacerlo de manera más explícita.

Este no es un problema solo de PHP. Como evidencia aquí hay una sección relevante de una guía de endurecimiento de Apache .

JimmyJames
fuente
1
¿Por qué el voto negativo?
JimmyJames
8

No puedo responder por la industria, pero puedo decirte por qué me alejé del sistema de archivos URL = a principios de la década de 2000 hacia las 'rutas' virtuales.

Al trabajar con PHP de la 'vieja escuela', si tiene 1000 páginas PHP, tendría 1000 archivos PHP que representan esas páginas. Cada duplicado de encabezado / pie de página incluye y posiblemente alguna otra lógica. Ahora digamos que necesitas cambiar eso. ¡Qué desastre tienes ahora en tus manos! Tienes que cambiar los 1000 archivos, o terminas con un revoltijo de código muy feo en el encabezado / pie de página para manejar todos los casos. Usando rutas virtuales, su lógica de encabezado / pie de página, lógica de conexión de base de datos y otras inicializaciones se incluyen una vez , punto. Mucho mejor para trabajar.

Otra razón es evitar la ambigüedad. A medida que crecen las aplicaciones, los encabezados / pies de página que se incluyen se vuelven más complejos. Por lo general, tenían anidadas propias que dependían de varias cosas. En el archivo PHP para la 'página', a menudo se encuentra la ambigüedad sobre si una variable se establece () o no. Al usar rutas virtuales y una aplicación donde se carga todo lo que necesita en cada carga de página, ya no tiene esa preocupación.

Por último (aunque hay otras razones, pero es la última que enumeraré), muchas de esas 1000 páginas representan código que se duplicaría. Entonces, después de refactorizar en un conjunto adecuado de clases y plantillas, el código se simplifica enormemente y puede hacer todo lo que quiera sin tener esos 1000 archivos.

Gran maestro B
fuente
¿Puedes decir más por qué terminarías con un código muy feo? Puedo ver la necesidad de cambiar 1000 archivos (suponiendo que sea actualizar el encabezado / pie de página incluido), pero ¿qué quieres decir con revoltijo de código feo?
Dennis
Vea el párrafo que acabo de agregar. Pero básicamente, a medida que extiende el código de encabezado / pie de página / inicialización para manejar más casos, especialmente si incluye condicionalmente otros archivos (era un mal hábito, pero muchos programadores PHP lo hicieron), termina con un código muy difícil de seguir .
GrandmasterB
5

No entraré en demasiados detalles sobre por qué esta separación es beneficiosa. El argumento principal es que separa la semántica (a qué estás intentando acceder realmente) de la implementación subyacente.

Teniendo en cuenta que los beneficios superan los costos como un hecho, lo cual sería una pregunta separada, no es difícil ver por qué se adoptó gradualmente. No creo que haya un solo evento que haya causado esto, aunque ciertamente estaría abierto a ser educado en esto.

Al menos en mi experiencia, inicialmente esto a menudo se hizo a través de la configuración de Apache, y presumiblemente otros servidores web también lo admitieron. Sin embargo, conceptualmente no hay una buena razón por la cual el servidor deba encargarse de esto. Después de todo, las rutas son específicas de la aplicación real, por lo que tiene sentido definirlas allí.

Esto cambió globalmente, pero como usted señala, gradualmente. Es casi seguro que la razón es muy simple: las buenas ideas se extienden a lo largo del tiempo. Esta es también la razón por la cual no es una sorpresa que el cambio haya ocurrido a nivel mundial. No es que todos se hayan reunido y hayan decidido hacerlo de esta manera. Más bien, cada proyecto adaptó este enfoque cuando pensaron que sería beneficioso (y los proyectos que no lo respaldaron finalmente desaparecieron).

te doblo
fuente
1

Los RFC ya construyeron los conceptos desde cero, con URI (que no adjuntaron ninguna semántica a la parte local) y URL como un caso especial que introdujo una semántica similar a la ruta para permitir que los documentos HTML usen enlaces relativos al documento URL base

La implementación obvia es asignar la parte local de la URL directamente al sistema de archivos, por lo que esto es lo que hicieron las configuraciones simples, ya sea que use una base de datos relacional dedicada para buscar un documento o aproveche la clave altamente optimizada de bajo costo general -la tienda de valor que ya tiene no importa al exterior, pero ciertamente afecta su estructura de costos para entregar los documentos.

Si tiene una aplicación web con datos persistentes, esa estructura de costos cambia: siempre tiene la sobrecarga de ejecutar la aplicación, e integrar la decodificación de URL hace que muchas funciones sean más fáciles de implementar, lo que reduce los costos.

Simon Richter
fuente
1

Al principio de los tiempos, las URL se asignaban directamente a las rutas de los archivos en el servidor porque es fácil y, de todos modos, no hay otra forma de hacerlo, ¿verdad? Si lo solicito /path/to/index.php, /path/to/index.phpcomenzaré desde el directorio raíz del sitio web (generalmente no del servidor en sí, el sitio web debe mantenerse en un directorio o subdirectorio más abajo).

Luego, después de un par de años, comenzamos a aprender sobre la reescritura, que está sirviendo a un recurso diferente al que aparentemente se solicitó. /request/path/to/index.phpen realidad puede servir /response/path/to/index.php.

Otro truco es esconderse index.php. Si le pido que /index.php?foo=bar&baz=quxel servidor pueda responder ocultándome index.phpasí: /?foo=bar&baz=quxtodo el tiempo, de todos index.phpmodos, sirve .

El siguiente paso, que es el más importante, es que aprendimos a redirigir todas las URL /index.php. Así que ahora, /path/to/some/pagese redirige silenciosamente a /index.php?path/to/some/page. Esto es un poco complicado, porque normalmente cada barra representa un nuevo subdirectorio, pero en este caso el servidor web está configurado para enviar la ruta como un parámetro, en lugar de buscarlo.

Ahora que tenemos esto, necesitamos una forma completamente diferente de pensar acerca de cómo está organizado el sitio web. Antes, era una colección suelta de diferentes páginas. Ahora, todo se enruta a través de una sola página de entrada. Esto hace que el sitio sea mucho más complicado, pero brinda oportunidades que antes no estaban disponibles, como la autenticación de usuarios en todo el sitio, la aplicación uniforme de encabezados, pies de página y estilos, etc.

Efectivamente convierte su sitio web de cien o mil aplicaciones (si considera que cada archivo es su propia aplicación) en una sola aplicación, mucho más complicada pero mucho más consistente.

Este es un gran salto, ya que no puede saber qué código se ejecutará simplemente mirando la URL. Ahora debe tener una comprensión profunda de cómo su marco particular traduce las rutas URL en rutas de código, y aunque existen similitudes entre los marcos, la mayoría son lo suficientemente diferentes como para que necesite cierta familiaridad para poder trabajar con el código.

En pocas palabras, fue una evolución gradual del descubrimiento, no un salto repentino, y cada desarrollador tuvo que pasar por el mismo viaje de descubrimiento. La curva de aprendizaje es bastante empinada, a menos que pueda comprender conceptos abstractos muy rápidamente.

CJ Dennis
fuente
-1

Como webdev desde hace mucho tiempo, creo que la llegada del control de historial sin navegación ( history.pushState()) en la época de HTML5 lo hizo práctico. Antes de eso, tenía que volver a cargar la página para actualizar la barra de URL, a menos que solo actualizara el fragmento ( /path#fragment). Este fragmento era invisible para el servidor (no está enrutado), por lo que la única forma de actualizar o marcar una página dinámica era a través de JavaScript.

Esto tiene implicaciones importantes para el SEO, y llevó a Google a desarrollar un esquema de "hashbang" que rara vez se usaba y que requería una asignación del lado del servidor de hashes dinámicos a URL físicas. Esto era difícil de manejar y no universal entre los robots, liderando el axioma (falso): "las arañas no pueden rastrear el contenido de ajax". Pero los beneficios del contenido de ajax son tangibles: intente usar google maps sin JS, por ejemplo.

La solución fue una forma de actualizar la barra de URL con un valor que se puede reflejar en el servidor (permitiendo marcadores y actualización sin JS), SIN recargar la página. Una vez que esta capacidad estaba disponible, los desarrolladores podían "navegar" por un sitio simplemente actualizando una "sección de contenido principal", una barra de URL y migas de pan. Esto significaba que todo el JS + CSS no necesitaba volverse a buscar + analizar, lo que permitía una transferencia MUCHO más rápida de página a página.

dandavis
fuente