Come e perché i moderni framework di applicazioni Web si sono evoluti per disaccoppiare le rotte URL dal file system?


67

Rispetto a circa 10 anni fa ho notato uno spostamento verso i framework usando lo stile di routing che disaccoppia il percorso dell'URL dal filesystem. Questo è generalmente realizzato con l'aiuto di un modello di controller frontale.

Vale a dire, quando prima, il percorso dell'URL era mappato direttamente al file system e quindi rifletteva esattamente i file e le cartelle sul disco, al giorno d'oggi i percorsi URL effettivi sono programmati per essere indirizzati a classi specifiche tramite la configurazione e, come tali, non riflettono più il file cartella di sistema e struttura dei file.

Domanda

Come e perché questo è diventato banale? Come e perché è stato deciso che è "migliore" al punto da abbandonare efficacemente l'approccio diretto al file una volta comune?

Altre risposte

C'è una risposta simile qui che va un po 'nel concetto di rotta e alcuni vantaggi e svantaggi: con i framework PHP, perché viene usato il concetto di "rotta"?

Ma non affronta gli aspetti del cambiamento storico, né come o perché questo cambiamento è avvenuto gradualmente, in cui oggigiorno alcuni nuovi progetti stanno praticamente utilizzando questo nuovo modello di stile di routing e direct-to-file è obsoleto o abbandonato.

Inoltre, la maggior parte dei vantaggi e degli svantaggi citati non sembra essere abbastanza significativa da giustificare un simile cambiamento globale. L'unico vantaggio che posso vedere guidando questo cambiamento forse è nascondere il sistema di file / cartelle all'utente finale e anche la mancanza di ?param=value&param2=value, il che rende gli URL un po 'più puliti. Ma quelli erano l'unico motivo del cambiamento? E se sì, perché c'erano questi motivi?

Esempi:

Conosco molto bene i framework PHP e molti framework moderni popolari usano questo approccio di routing disaccoppiato. Per farlo funzionare, devi impostare la riscrittura dell'URL in Apache o un server Web simile, in cui la funzionalità dell'applicazione Web in genere non viene più attivata tramite un percorso URL diretto al file.

Zend espressivo

https://docs.zendframework.com/zend-expressive/features/router/aura/
https://docs.zendframework.com/zend-expressive/features/router/fast-route/
https: //docs.zendframework. com / Zend-espressivo / caratteristiche / router / ZF2 /

Zend Framework

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


14
c'è stato davvero un tale cambiamento? o forse la maggior parte delle lingue / dei framework non ha mai usato la mappatura diretta del filesystem? forse è solo PHP che si sta avvicinando al resto della mente sana? le tue osservazioni sono errate secondo me, quindi non c'è una buona risposta. anche "shift" di cui parli è avvenuto solo nel mondo PHP. ma è una domanda troppo ampia secondo me ...
rsm

2
@rsm Ho avuto una prima reazione simile, ma a pensarci bene, è davvero qualcosa che è stato fatto in molte lingue e piattaforme che lo rendono una fonte di vulnerabilità davvero comune.
JimmyJames,

6
@rsm, questo può essere più evidente nei framework PHP, ma per usare un altro modo - a un certo momento, prima che qualsiasi framework prendesse davvero piede, sia ASP, .NET, PHP, JSP, ecc., il web usava principalmente direct- approccio al file. Perché tutti questi quadri si sono sviluppati per utilizzare l'approccio disaccoppiato? Tecnicamente, l'approccio direct-to-file è ancora fattibile e sono sicuro che i framework moderni possano usarlo. O possono? Forse non possono, e forse ci sono buone ragioni per cui non lo fanno? Quali sarebbero questi motivi ...? Non forniscono nemmeno un modo o un plug-in per farlo, hanno semplicemente sradicato del tutto il file diretto.
Dennis,

2
Questo (in parte) non riguarda anche la visualizzazione di un URL (un localizzatore , come trovare una risorsa) come URI (e identificatore )?
Hagen von Eitzen,

2
Lettura correlata dalla storia antica: Gli URI fantastici non cambiano - Tim Berners-Lee, 1998
Michael Hampton,

Risposte:


72

Nella sua forma più semplice, un sito Web serve file statici. Mappare il percorso URL su un percorso file è la scelta più ovvia; in sostanza, è un sito FTP di sola lettura.

Quindi le persone volevano cambiare il contenuto della pagina con alcuni script. Il modo più semplice è incorporare un linguaggio di scripting nella pagina ed eseguirlo attraverso un interprete. Ancora una volta, dato il percorso già esistente -> percorso percorso file, questo è stato abbastanza semplice.

Ma davvero, stai eseguendo quel file come argomento per l'interprete ora. Devi identificare quando la richiesta è per un file statico e quando è per qualcosa che devi interpretare.

Una volta che inizi a utilizzare linguaggi compilati più avanzati, sei ancora più divorziato dal percorso del file.

Inoltre, il tuo server web sta già memorizzando nella cache i file statici e sta facendo ogni sorta di ottimizzazione, ciò significa che colpire il file system è l'eccezione piuttosto che la regola. A questo punto, il vecchio percorso del file system di collegamento è più un ostacolo che un aiuto.

Ma penso che il vero cambiamento del mare sia arrivato quando gli utenti volevano sbarazzarsi dell'estensione del file dal percorso. Ottenere myPage.asp o myPage.php era qualcosa che confondeva le persone "normali" e interferiva con la SEO.

Poiché l'utente vede il percorso, è diventato parte dell'interfaccia utente del Web e, come tale, deve essere completamente privo di limitazioni tecniche. Abbiamo perso il "www" e praticamente tutto è un ".com". Più URL punteranno alla stessa pagina.

Se guadagno di più con mydomain.com/sale vs www.mydomain.co.uk/products/sale.aspx, non voglio che limiti tecnici mi ostacolino.


7
Ho sempre pensato che il desiderio di nascondere le estensioni dei file fosse in parte "sicurezza per oscurità" - rendendo un po 'più difficile dire quale tecnologia fosse impiegata da un sito al fine di rendere meno facile il targeting per particolari exploit collegati / noti di determinati server e tecnici all'epoca
Caius Jard

20
@CaiusJard fa parte di esso, ma un'altra parte è l'agnosticismo tecnologico: avendo sostituito file.html nei nostri percorsi, non volevamo rimanere bloccati con un altro interruttore in seguito (ad esempio, da file.phtml a file.php, o anche a file.asp). Ma dal momento che stiamo dissociando l'URL e il percorso del filesystem (usando il routing o altro) per accedere alle risorse costruite dai record del database e / o da altre fonti, perché avere un'estensione nell'URL?
HorusKol,

39
L'agnosticismo della tecnologia @HorusKol non significa nemmeno dover cambiare tutti i file nel tuo percorso. Essere in grado di cambiare le tecnologie di backend senza interrompere il flusso di lavoro e i segnalibri dei clienti e senza distruggere il tuo SEO può essere enorme .
Shane,

7
È interessante notare che non è mai stato raccomandato di avere estensioni di file nell'URI, quindi avrebbero dovuto essere disaccoppiate dal file system all'inizio. Il primo riferimento che posso trovare per questo è del 1998 , che in realtà precede la maggior parte degli sviluppi descritti in questa risposta.
Konrad Rudolph,

8
Ai vecchi tempi mydomain.com/sale funzionava ancora; è stato reindirizzato a / sale / e caricato correttamente (la tua pagina era mydomain.com/sale/index.aspx ma nessuno ha mai visto index.aspx).
Joshua,

39

Puoi leggere un white paper di Roy Fielding su REST (State State Transfer) in merito a quando e perché . Il primo framework di cui ero a conoscenza che faceva la distinzione tra una risorsa e un file era Ruby on Rails, introducendo il concetto di URL al routing del codice.

I concetti principali dietro REST che erano trasformativi erano:

  • Un URL rappresenta una risorsa
  • Quella risorsa può avere più rappresentazioni
  • L'URL non deve interrompersi se l'applicazione viene ristrutturata
  • Le applicazioni dovrebbero abbracciare l'apolidia del web

Lo svantaggio principale di avere file forniti direttamente dall'URL è che si verificano i seguenti problemi:

  • I collegamenti alle risorse vengono costantemente interrotti man mano che i siti Web vengono riorganizzati
  • Risorsa e rappresentazione sono legate insieme

Penso che sia importante fornire anche un certo equilibrio:

  • Non tutte le risorse sono uguali per importanza. Ecco perché hai ancora risorse basate sullo stile offerte direttamente (CSS, JavaScript / EcmaScript, immagini)
  • Esistono perfezionamenti di REST come HATEOAS che supportano meglio le app a pagina singola.

quando dici rappresentazione vuoi dire cose come JSON / HTML / TEXT / etc? Ho vagamente familiarità con REST, ma immagino che anche con REST tu debba avere una specie di grilletto per cambiare la rappresentazione della risposta ...
Dennis

@Dennis, si. HTTP ha un numero di intestazioni che possono essere utilizzate per suggerire la forma desiderata ( developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation ) e REST si basava sull'abbracciare i punti di forza di HTTP. Tuttavia, non è ancora raro che un'app abbia un modo proprietario di negoziare il contenuto desiderato.
Berin Loritsch,

5
CGI (1993), Servlets (1997) e JSP (1999) hanno spesso disaccoppiato gli URL dal filesystem e prima del REST (2000). Tuttavia, questa risposta è sostanzialmente corretta nell'identificare le ragioni della popolarità del modello di progettazione: REST, Java Struts e Ruby on Rails hanno un'enorme influenza sulla popolarità del 21 ° secolo nel separare le risorse dalle rappresentazioni.
Dal

1
Secondo l'articolo di Fielding, "La prima edizione di REST è stata sviluppata tra ottobre 1994 e agosto 1995"
Connor

1
@dcorking, CGI a quel tempo non separava gli URL dai file, ma eseguiva il file invece 9 volte su 10. I servlet potrebbero essere la corrispondenza più vicina, ma se stai parlando del concetto di route e hai uno spazio URL progettato , che è arrivato con Rails e framework simili.
Berin Loritsch,

20

Non penso che sia un artefatto dei moderni framework di applicazioni Web, è principalmente un artefatto di pagine dinamiche che servono in generale.

In passato c'erano principalmente pagine Web statiche, in cui un software serviva singoli file dal file system attraverso il loro percorso. Lo hanno fatto principalmente perché la mappatura 1: 1 dei percorsi URL ai percorsi del file system (con una directory designata come root Web) era la scelta ovvia, sebbene fosse comune anche la riscrittura degli URL (ad esempio per effettuare reindirizzamenti dopo lo spostamento dei file).

Poi è arrivata l'era della pubblicazione di contenuti dinamici. Gli script CGI (e tutto si è evoluto da loro) hanno creato le pagine al volo, sostenute da un database di qualche tipo. OTTENERE i parametri nell'URL è diventato un luogo comune, ad esempio en.wikipedia.org/w/index.php?title=Path_(computer) .

Tuttavia è più intuitivo avere un URL leggibile composto da soli segmenti di percorso. Quindi le applicazioni dinamiche hanno mappato percorsi semplici (ad esempio en.wikipedia.org/wiki/Path_(computing) ) ai parametri e questi mapping sono noti come "route".

Forse questo approccio sembra più recente in quanto ha guadagnato popolarità quando l'importanza dell'usabilità è stata riconosciuta più ampiamente ed è diventata anche parte della SEO. Questo è probabilmente il motivo per cui è stato integrato direttamente nei grandi framework web.


12

Uno dei motivi è che il caricamento di un file dal disco su ogni richiesta è lento, quindi i server Web hanno iniziato a creare modi per memorizzare nella cache i file in memoria, quindi se hai intenzione di provare a tenerlo in memoria comunque, perché è importante dove si trovava disco?

Uno dei motivi è che molti framework Web sono scritti in linguaggi compilati, quindi non hai nemmeno una struttura di file sul disco, solo un jarfile o altro. Le lingue interpretate prendevano in prestito idee che gli piacevano da quelle compilate.

Uno dei motivi è il desiderio di percorsi più semantici e dinamici, come https://softwareengineering.stackexchange.com/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes. Ovviamente, non vuoi un /var/www/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes.phpfile. In passato era necessario creare regole di riscrittura degli URL nella configurazione del server Web per creare percorsi come questo. Ora è solo una modifica del codice, che è molto più semplice dal punto di vista operativo.


Non è necessario riscrivere l'URL per quell'esempio.
Yay295

1
È gestito dal codice che riconosce la prima parte del percorso e utilizza il numero / 363517 / per cercare la domanda in un database. Niente a che vedere con il web server stesso, ma un'applicazione ...
Will Crawford,

11

Uno dei principali motivi è probabile che questo approccio di mappatura di URI su percorsi di file abbia portato a un gran numero di rilasci accidentali di dati tramite File Path Traversal

Quando si mappa il percorso al file system, significa che è necessario verificare che ogni percorso ricevuto come richiesta sia mappato ai file che dovrebbero essere accessibili ai client. Un approccio semplice per garantire che ciò non accada è quello di eliminare la mappatura trasparente e farlo in modo più esplicito.

Questo non è un problema solo per PHP. Come prova qui è una sezione pertinente di una guida di indurimento di Apache .


1
Perché il downvote?
JimmyJames,

8

Non posso rispondere per il settore, ma posso dirti perché mi sono allontanato dall'URL = file system nei primi anni 2000 verso "percorsi" virtuali.

Lavorando con PHP "old school", se hai 1000 pagine PHP, avresti 1000 file PHP che rappresentano quelle pagine. Ciascuna intestazione / piè di pagina duplicante include e possibilmente qualche altra logica. Ora diciamo che devi cambiarlo. Che casino ora hai tra le mani! O devi cambiare tutti i 1000 file o finisci con un miscuglio di codice molto brutto nell'intestazione / piè di pagina per gestire tutti i casi. Utilizzando route virtuali, la logica dell'intestazione / piè di pagina, la logica di connessione al database e altre inizializzazioni sono incluse una volta , punto. Molto meglio con cui lavorare.

Un altro motivo è evitare l'ambiguità. Man mano che le applicazioni crescono, le intestazioni / i piè di pagina che vengono inclusi diventano più complessi. Di solito avevano nidificati inclusioni proprie che dipendevano da varie cose. Nel file PHP per la 'pagina', spesso hai riscontrato ambiguità sul fatto che una variabile isset () o meno. Utilizzando percorsi virtuali e un'applicazione in cui tutto il necessario è caricato su ogni caricamento di pagina, non hai più questo problema.

Infine (anche se ci sono altri motivi, ma è l'ultimo elenco che elencherò), molte di quelle 1000 pagine rappresentano il codice da duplicare. Quindi, dopo aver eseguito il refactoring in un set appropriato di classi e modelli, il codice è notevolmente semplificato e puoi fare tutto ciò che vuoi fare senza avere quei 1000 file.


puoi dire di più perché dovresti finire con un codice molto brutto? Riesco a vedere la necessità di cambiare 1000 file (supponendo che si tratti di aggiornare le intestazioni / piè di pagina), ma cosa intendi con miscuglio di codice brutto?
Dennis,

Vedi il paragrafo che ho appena aggiunto. Ma fondamentalmente, quando estendi il codice di intestazione / piè di pagina / inizializzazione per gestire più casi, specialmente se includi condizionalmente altri file (era una cattiva abitudine, ma molti programmatori PHP lo facevano), finisci con un codice molto difficile da seguire .
GrandmasterB,

5

Non entrerò in troppi dettagli sul perché questa separazione sia vantaggiosa. L'argomento principale è che separa la semantica (a cosa stai effettivamente tentando di accedere) dall'implementazione sottostante.

Partendo dal presupposto che i benefici superano i costi come un dato - che sarebbe una domanda separata - non è difficile capire perché sia ​​stato gradualmente adottato. Non penso che ci sia stato un singolo evento che ha causato questo, anche se sarei sicuramente aperto a essere istruito su questo.

Almeno nella mia esperienza, inizialmente questo è stato spesso fatto tramite la configurazione di Apache - e presumibilmente anche altri server web lo hanno supportato. Tuttavia, concettualmente non esiste una buona ragione per cui il server dovrebbe essere incaricato di questo. Dopotutto, i percorsi sono specifici dell'applicazione effettiva, quindi ha senso definirli lì.

Questo è cambiato a livello globale, ma come fai notare, gradualmente. La ragione di ciò è quasi certamente molto semplice: le buone idee si sono diffuse nel tempo. Questo è anche il motivo per cui non è così sorprendente che il cambiamento sia avvenuto a livello globale. Non è che tutti si sono riuniti e hanno deciso di farlo in questo modo. Piuttosto, ogni progetto ha adattato questo approccio quando ha pensato che sarebbe stato utile (e i progetti che non lo hanno supportato alla fine sono scomparsi).


1

Gli RFC hanno già creato i concetti da zero, con gli URI (che non hanno collegato alcuna semantica alla parte locale) e gli URL come un caso speciale che ha introdotto la semantica simile a un percorso per consentire ai documenti HTML di utilizzare i collegamenti relativi al documento URL di base.

L'implementazione ovvia è mappare la parte locale dell'URL direttamente sul file system, quindi è ciò che hanno fatto le semplici configurazioni: se si utilizza un database relazionale dedicato per cercare un documento o sfruttare la chiave low-over altamente ottimizzata -valore negozio che hai già non ha importanza all'esterno, ma influisce sicuramente sulla struttura dei costi per la pubblicazione dei documenti.

Se si dispone di un'applicazione Web con dati persistenti, la struttura dei costi cambia: si ha sempre il sovraccarico di eseguire l'applicazione e l'integrazione della decodifica URL in essa semplifica l'implementazione di molte funzionalità, riducendo i costi.


1

All'inizio del tempo, gli URL mappati direttamente ai percorsi dei file sul server perché è facile e non c'è altro modo di farlo comunque, vero? Se lo chiedo /path/to/index.php, inizierò /path/to/index.phpdalla directory principale del sito Web (di solito non dal server stesso, il sito Web dovrebbe essere tenuto in una directory o in una sottodirectory più in basso).

Poi, dopo un paio d'anni, abbiamo iniziato a conoscere la riscrittura, che serve una risorsa diversa da quella che apparentemente era stata chiesta. /request/path/to/index.phppuò effettivamente servire /response/path/to/index.php.

Un altro trucco si sta nascondendo index.php. Se chiedo che /index.php?foo=bar&baz=quxil server possa rispondere nascondendosi in questo index.phpmodo :, per /?foo=bar&baz=quxtutto il tempo effettivamente serve index.phpcomunque.

Il passaggio successivo, che è il più importante, è che abbiamo imparato a reindirizzare tutti gli URL /index.php. Quindi ora, /path/to/some/pageviene reindirizzato silenziosamente a /index.php?path/to/some/page. Questo è un po 'complicato, perché normalmente ogni barra rappresenta una nuova sottodirectory, ma in questo caso il server Web è configurato per inviare il percorso come parametro, invece di cercarlo.

Ora che abbiamo questo, abbiamo bisogno di un modo completamente diverso di pensare a come è organizzato il sito web. Prima era una raccolta di pagine diverse. Ora, tutto viene instradato attraverso una singola pagina di entrata. Ciò rende il sito molto più complicato, ma offre opportunità che prima non erano disponibili, come l'autenticazione dell'utente a livello di sito, l'applicazione uniforme di intestazioni, piè di pagina e stili, ecc.

Trasforma efficacemente il tuo sito Web di centinaia o migliaia di app (se consideri ogni file come la propria app) in un'unica app, molto più complicata ma molto più coerente.

Questo è un grande salto, poiché non puoi più dire quale codice verrà eseguito semplicemente guardando l'URL. È ora necessario avere una conoscenza approfondita di come il proprio framework particolare traduce i percorsi URL in percorsi di codice e, sebbene esistano somiglianze tra i framework, la maggior parte sono abbastanza diversi da richiedere una certa familiarità per poter lavorare con il codice.

Per farla breve, è stata una graduale evoluzione della scoperta, non un salto improvviso, e ogni sviluppatore ha dovuto praticamente percorrere lo stesso viaggio di scoperta. La curva di apprendimento è piuttosto ripida, a meno che non si riesca a cogliere concetti astratti molto rapidamente.


-1

Come webdev di lunga data, penso che l'avvento del controllo della cronologia senza navigazione ( history.pushState()) intorno al tempo di HTML5 abbia reso questo pratico. Prima di ciò, dovevi ricaricare la pagina per aggiornare la barra degli URL, a meno che non avessi aggiornato solo il frammento ( /path#fragment). Questo frammento era invisibile al server (non è instradato), quindi l'unico modo per aggiornare o aggiungere una pagina dinamica ai segnalibri era tramite JavaScript.

Ciò ha importanti implicazioni per la SEO e ha portato Google a sviluppare uno schema "hashbang" usato raramente che richiedeva una mappatura lato server di hash dinamici su URL fisici. Questo era ingombrante e non universale tra i robot, portando l'assioma (falso): "i ragni non possono strisciare il contenuto ajax". Ma i vantaggi del contenuto ajax sono tangibili: prova ad usare google maps senza JS per esempio.

La soluzione è stata un modo per aggiornare la barra degli URL con un valore che può essere rispecchiato sul server (consentendo ai segnalibri e all'aggiornamento senza JS), SENZA ricaricare la pagina. Una volta disponibile questa funzionalità, gli sviluppatori hanno potuto "navigare" in un sito semplicemente aggiornando una "sezione di contenuto principale", una barra degli URL e breadcrumb. Ciò significava che tutto il CSS JS + non aveva bisogno di essere recuperato + analizzato, consentendo un trasferimento da pagina a pagina MOLTO più veloce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.