Bagaimana dan mengapa kerangka kerja aplikasi web modern berkembang untuk memisahkan rute URL dari sistem file?

67

Dibandingkan dengan sekitar 10 tahun yang lalu saya telah mencatat pergeseran menuju kerangka kerja menggunakan gaya perutean yang memisahkan jalur URL dari sistem file. Ini biasanya dilakukan dengan bantuan pola pengontrol-depan.

Yaitu, ketika sebelumnya, jalur URL dipetakan langsung ke sistem file dan karena itu mencerminkan file dan folder pada disk, saat ini, jalur URL aktual diprogram untuk diarahkan ke kelas-kelas tertentu melalui konfigurasi, dan dengan demikian, tidak lagi mencerminkan file folder sistem dan struktur file.

Pertanyaan

Bagaimana dan mengapa ini menjadi hal biasa? Bagaimana dan mengapa diputuskan bahwa itu "lebih baik" ke titik di mana pendekatan direct-to-file yang dulu biasa secara efektif ditinggalkan?

Jawaban Lain

Ada jawaban serupa di sini yang sedikit masuk ke konsep rute dan beberapa manfaat dan kelemahannya: Dengan kerangka kerja PHP, mengapa konsep "rute" digunakan?

Tapi itu tidak membahas aspek perubahan historis, atau bagaimana atau mengapa perubahan ini terjadi secara bertahap, ke tempat proyek baru saat ini cukup banyak menggunakan pola gaya perutean baru ini dan direct-to-file sudah usang atau ditinggalkan.

Selain itu, sebagian besar manfaat dan kelemahan yang disebutkan, tampaknya tidak cukup signifikan untuk menjamin perubahan global semacam itu. Satu-satunya manfaat yang saya dapat melihat mendorong perubahan ini mungkin menyembunyikan sistem file / folder dari pengguna akhir, dan juga kekurangan ?param=value&param2=value, yang membuat URL terlihat sedikit lebih bersih. Tetapi apakah itu satu-satunya alasan perubahan itu? Dan jika ya, mengapa mereka alasan di balik itu?

Contoh:

Saya paling akrab dengan kerangka kerja PHP dan banyak kerangka kerja modern populer menggunakan pendekatan routing yang dipisahkan ini. Untuk membuatnya berfungsi, Anda mengatur penulisan ulang URL di Apache atau server web serupa, ke tempat fungsionalitas aplikasi web biasanya tidak lagi dipicu melalui jalur URL langsung ke file.

Zend Expressive

https://docs.zendframework.com/zend-expressive/features/router/aura/
https://docs.zendframework.com/zend-expressive/features/router/fast-route/
https: //docs.zendframework. com / zend-ekspresif / fitur / 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/id/development/routing.html

Dennis
sumber
14
apakah memang ada perubahan seperti itu? atau mungkin sebagian besar bahasa / kerangka kerja tidak pernah menggunakan pemetaan sistem file langsung? mungkin itu hanya PHP yang bisa menyusul sisa waras? menurut saya pengamatan Anda salah, jadi tidak ada jawaban yang bagus. juga "shift" yang Anda sebutkan hanya terjadi di dunia PHP. tapi itu pertanyaan yang terlalu luas menurut saya ...
rsm
2
@rsm Saya memiliki reaksi pertama yang serupa tetapi pada pemikiran lebih lanjut, itu benar-benar sesuatu yang telah dilakukan di banyak bahasa dan platform yang menjadikannya sumber kerawanan yang sangat umum.
JimmyJames
6
@rsm, ini mungkin lebih jelas dalam kerangka PHP, tetapi untuk menggunakan cara lain - pada waktu tertentu, sebelum kerangka kerja benar-benar tertangkap, baik itu ASP, .NET, PHP, JSP, dll, web sebagian besar digunakan langsung- pendekatan ke file. Mengapa semua kerangka kerja ini dikembangkan untuk menggunakan pendekatan yang dipisahkan? Secara teknis, pendekatan direct-to-file masih layak, dan saya yakin kerangka kerja modern dapat menggunakannya. Atau bisakah mereka? Mungkin mereka tidak bisa, dan mungkin ada alasan bagus mengapa mereka tidak? Apa alasannya ..? Mereka bahkan tidak menyediakan cara atau plugin untuk melakukan ini, mereka hanya menghapus secara langsung ke file.
Dennis
2
Bukankah ini (sebagian) juga tentang melihat URL ( pelacak , bagaimana menemukan sumber daya) sebagai URI (dan pengidentifikasi )?
Hagen von Eitzen
2
Bacaan terkait dari sejarah kuno: URI Keren Jangan Berubah - Tim Berners-Lee, 1998
Michael Hampton

Jawaban:

72

Dalam bentuknya yang paling dasar, situs web menyajikan file statis. Memetakan jalur URL ke jalur file adalah pilihan yang paling jelas; pada dasarnya, ini adalah situs FTP read-only.

Kemudian orang ingin mengubah konten halaman dengan beberapa skrip. Cara termudah adalah dengan menanamkan bahasa scripting ke halaman dan menjalankannya melalui seorang juru bahasa. Sekali lagi, mengingat jalur yang sudah ada -> perutean jalur file, ini cukup sederhana.

Tapi sungguh, Anda menjalankan file itu sebagai argumen untuk penerjemah sekarang. Anda harus mengidentifikasi kapan permintaan untuk file statis dan kapan untuk sesuatu yang perlu Anda tafsirkan.

Setelah Anda mulai menggunakan bahasa yang dikompilasi lebih lanjut, Anda bahkan lebih bercerai dari lokasi file.

Plus, server web Anda sudah melakukan caching file statis dan melakukan segala macam optimasi, itu berarti memukul sistem file adalah pengecualian daripada aturannya. Pada titik ini, jalur sistem file tautan lama lebih merupakan penghalang daripada bantuan.

Tapi saya pikir perubahan nyata terjadi ketika pengguna ingin menyingkirkan ekstensi file dari path. Mendapatkan myPage.asp atau myPage.php adalah sesuatu yang membingungkan orang 'normal' dan mengganggu SEO.

Karena pengguna melihat jalan, itu telah menjadi bagian dari UI web, dan karena itu, ia harus sepenuhnya bebas dari batasan teknis apa pun. Kami telah kehilangan 'www' dan hampir semuanya adalah '.com'. Beberapa URL akan mengarah ke halaman yang sama.

Jika saya menghasilkan lebih banyak uang dengan mydomain.com/sale vs www.mydomain.co.uk/products/sale.aspx, maka saya tidak ingin ada batasan teknis yang menghalangi saya.

Ewan
sumber
7
Saya selalu berpikir bahwa keinginan untuk menyembunyikan ekstensi file sebagian adalah "keamanan karena ketidakjelasan" - membuatnya sedikit lebih sulit untuk mengatakan teknologi apa yang digunakan oleh suatu situs untuk membuatnya lebih mudah untuk ditargetkan untuk eksploitasi tertentu yang diketahui / diketahui dari server tertentu. dan teknisi saat itu
Caius Jard
20
@CaiusJard yang merupakan bagian dari itu, tetapi bagian lain adalah teknologi agnostisisme - setelah mengganti file.html di jalur kami, kami tidak ingin terjebak dengan sakelar lain nanti (misalnya, file.phtml ke file.php, atau bahkan untuk file.asp). Tetapi karena kita memisahkan URL dan jalur sistem file (menggunakan perutean atau apa pun) untuk mengakses sumber daya yang dibangun dari catatan basis data dan / atau sumber lain, mengapa memiliki ekstensi di URL sama sekali?
HorusKol
39
@HorusKol Teknologi agnostisisme bahkan bukan hanya tentang harus mengubah semua file di jalur Anda. Mampu mengubah teknologi backend tanpa memutus alur kerja dan bookmark pelanggan Anda dan tanpa merusak SEO Anda bisa sangat besar .
Shane
7
Menariknya tidak pernah direkomendasikan untuk memiliki ekstensi nama file di URI, jadi mereka harus dipisahkan dari sistem file sejak awal. Referensi paling awal yang dapat saya temukan untuk ini adalah dari tahun 1998 , yang sebenarnya mendahului sebagian besar perkembangan yang dijelaskan dalam jawaban ini.
Konrad Rudolph
8
Di masa lalu mydomain.com/sale masih berfungsi; itu dialihkan ke / sale / dan dimuat dengan baik (halaman Anda adalah mydomain.com/sale/index.aspx tetapi tidak ada yang pernah melihat index.aspx).
Joshua
39

Anda dapat melihat ke buku putih oleh Roy Fielding di REpresentational State Transfer (REST) mengenai kapan dan mengapa . Kerangka pertama yang saya sadari yang membuat perbedaan antara sumber daya dan file adalah Ruby on Rails - memperkenalkan konsep URL ke routing kode.

Konsep utama di balik REST yang bersifat transformasional adalah:

  • URL mewakili sumber daya
  • Sumber daya itu dapat memiliki banyak representasi
  • URL tidak boleh rusak jika aplikasi direstrukturisasi
  • Aplikasi harus merangkul kewarganegaraan web

Kelemahan utama dari memiliki file yang dilayani langsung oleh URL adalah bahwa Anda mengalami masalah berikut:

  • Tautan sumber daya terus-menerus rusak karena situs web ditata ulang
  • Sumber daya dan representasi saling terkait

Saya pikir penting untuk memberikan keseimbangan yang adil juga:

  • Tidak semua sumber daya sama pentingnya. Itu sebabnya Anda masih memiliki sumber daya berbasis gaya yang dilayani secara langsung (CSS, JavaScript / EcmaScript, gambar)
  • Ada penyempurnaan REST seperti HATEOAS yang lebih baik mendukung aplikasi satu halaman.
Berin Loritsch
sumber
ketika Anda mengatakan representasi, apakah maksud Anda hal-hal seperti JSON / HTML / TEXT / etc? Saya agak akrab dengan REST, tetapi saya membayangkan bahkan dengan REST Anda harus memiliki semacam pemicu untuk mengubah representasi respons ...
Dennis
@ Dennis, ya. HTTP memiliki sejumlah tajuk yang dapat digunakan untuk memberi petunjuk pada formulir yang diinginkan ( developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation ) dan REST adalah tentang merangkul kekuatan HTTP. Namun, itu masih tidak biasa bagi suatu aplikasi untuk memiliki cara kepemilikan untuk menegosiasikan konten yang diinginkan.
Berin Loritsch
5
CGI (1993), Servlets (1997) dan JSP (1999) sering memisahkan URL dari sistem file, dan REST pra-tanggal (2000). Namun jawaban ini pada dasarnya benar dalam mengidentifikasi alasan popularitas pola desain: REST, Java Struts dan Ruby on Rails memiliki pengaruh besar pada popularitas abad ke-21 dalam memisahkan sumber daya dari representasi.
bekerja
1
Menurut makalah Fielding, "Edisi pertama REST dikembangkan antara Oktober 1994 dan Agustus 1995"
Connor
1
@dcorking, CGI pada saat itu tidak memisahkan URL dari file, itu hanya menjalankan file, bukan 9 kali dari 10. Servlet mungkin adalah yang paling cocok, tetapi jika Anda berbicara tentang konsep rute dan memiliki ruang url yang dirancang , yang datang dengan Rails dan kerangka kerja seperti itu.
Berin Loritsch
20

Saya tidak berpikir itu adalah artefak dari kerangka kerja aplikasi web modern , ini sebagian besar merupakan artefak dari penyajian halaman dinamis secara umum.

Di masa lalu ada sebagian besar halaman web statis, di mana sebuah perangkat lunak melayani file individual dari sistem file melalui jalur mereka. Mereka melakukan sebagian besar karena pemetaan 1: 1 jalur URL ke file jalur sistem (dengan satu direktori ditetapkan sebagai root web) adalah pilihan yang jelas, meskipun penulisan ulang URL (misalnya untuk membuat arahan ulang setelah memindahkan file) juga umum.

Kemudian tibalah zaman menyajikan konten dinamis. Script CGI (dan semuanya berevolusi dari mereka) memang membuat halaman on the fly, didukung oleh semacam database. GET parameter di URL menjadi hal biasa, misalnya en.wikipedia.org/w/index.php?title=Path_(computing) .

Namun lebih ramah pengguna untuk memiliki URL yang dapat dibaca yang hanya terdiri dari segmen jalur. Jadi aplikasi dinamis memetakan jalur sederhana (misalnya en.wikipedia.org/wiki/Path_(computing) ) ke parameter, dan pemetaan ini dikenal sebagai "rute".

Mungkin pendekatan ini terasa lebih baru karena memperoleh popularitas ketika pentingnya kegunaan diakui lebih luas, dan juga menjadi bagian dari SEO. Ini mungkin alasan mengapa itu dibangun langsung ke dalam kerangka web besar.

Bergi
sumber
12

Salah satu alasannya adalah bahwa memuat file dari disk pada setiap permintaan lambat, sehingga server web mulai membuat cara untuk men-cache file dalam memori, maka jika Anda akan tetap menyimpannya di memori, mengapa itu menjadi masalah di mana ia berada di disk?

Salah satu alasannya adalah bahwa banyak kerangka kerja web ditulis dalam bahasa yang dikompilasi, sehingga Anda bahkan tidak memiliki struktur file pada disk, hanya jarfile atau apa pun. Bahasa yang ditafsirkan meminjam ide yang mereka sukai dari yang dikompilasi.

Salah satu alasannya adalah keinginan untuk rute yang lebih semantik dan dinamis https://softwareengineering.stackexchange.com/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes. Jelas, Anda tidak menginginkan /var/www/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes.phpfile. Anda biasa membuat aturan penulisan ulang url di konfigurasi server web untuk membuat rute seperti ini. Sekarang ini hanya perubahan kode, yang jauh lebih sederhana secara operasional.

Karl Bielefeldt
sumber
Anda tidak perlu menulis ulang url untuk contoh itu.
Yay295
1
Ini ditangani oleh kode yang mengenali bagian pertama dari jalur, dan menggunakan nomor / 363517 / untuk mencari pertanyaan dalam database. Tidak ada hubungannya dengan server web itu sendiri, tetapi sebuah aplikasi ...
Will Crawford
11

Salah satu alasan utama adalah kemungkinan bahwa pendekatan pemetaan URI ke file paths telah menyebabkan sejumlah besar rilis data tanpa disengaja melalui File Path Traversal

Ketika Anda memetakan jalur ke sistem file, itu berarti bahwa Anda kemudian perlu memeriksa bahwa setiap jalur yang Anda terima sebagai permintaan memetakan file yang harus dapat diakses melalui ke klien. Pendekatan sederhana untuk menjamin hal yang tidak terjadi adalah menghilangkan pemetaan yang transparan dan melakukannya secara lebih eksplisit.

Ini bukan masalah khusus PHP. Sebagai bukti di sini adalah bagian yang relevan dari panduan pengerasan Apache .

JimmyJames
sumber
1
Mengapa downvote?
JimmyJames
8

Saya tidak bisa menjawab untuk industri ini, tetapi saya dapat memberi tahu Anda mengapa saya pindah dari URL = sistem file pada awal tahun 2000 ke arah 'rute' virtual.

Bekerja dengan PHP 'jadul', jika Anda memiliki 1000 halaman PHP, Anda akan memiliki 1000 file PHP yang mewakili halaman-halaman itu. Setiap header / footer duplikat termasuk dan mungkin beberapa logika lainnya. Sekarang katakanlah Anda perlu mengubahnya. Sungguh berantakan sekarang di tangan Anda! Anda harus mengubah semua 1000 file, atau berakhir dengan tumpukan kode yang sangat jelek di header / footer untuk menangani semua case. Menggunakan rute virtual, logika header / footer Anda, logika koneksi database, dan inisialisasi lainnya dimasukkan satu kali , titik. Jauh lebih baik untuk dikerjakan.

Alasan lain adalah untuk menghindari ambiguitas. Dengan bertambahnya aplikasi, header / footer yang disertakan menjadi lebih kompleks. Mereka biasanya bersarang termasuk milik mereka sendiri yang bergantung pada berbagai hal. Dalam file PHP untuk 'halaman', sering kali Anda menemui ambiguitas tentang apakah variabel mengeluarkan () atau tidak. Menggunakan rute virtual, dan aplikasi tempat semua yang Anda butuhkan dimuat pada setiap pemuatan halaman, Anda tidak lagi khawatir.

Terakhir (meskipun ada alasan lain, tetapi ini adalah daftar terakhir yang saya buat), banyak dari 1.000 halaman itu mewakili kode yang akan diduplikasi. Jadi setelah refactoring ke dalam set kelas dan template yang tepat, kode ini sangat disederhanakan dan Anda dapat melakukan semua yang ingin Anda lakukan tanpa memiliki 1000 file tersebut.

GrandmasterB
sumber
dapatkah Anda mengatakan lebih banyak mengapa Anda berakhir dengan kode yang sangat jelek? Saya bisa melihat kebutuhan untuk mengubah 1000 file (dengan asumsi itu adalah untuk memperbarui header / footer termasuk), tetapi apa yang Anda maksud dengan tumpukan kode jelek?
Dennis
Lihat paragraf yang baru saja saya tambahkan. Tetapi pada dasarnya, ketika Anda memperpanjang kode header / footer / inisialisasi untuk menangani lebih banyak kasus, terutama jika Anda memasukkan file lain secara kondisional (itu kebiasaan buruk, tetapi banyak programmer PHP yang melakukannya), Anda berakhir dengan sangat sulit untuk mengikuti kode .
GrandmasterB
5

Saya tidak akan membahas terlalu detail mengapa pemisahan ini bermanfaat. Argumen utama adalah bahwa ia memisahkan semantik (apa yang sebenarnya Anda coba akses) dari implementasi yang mendasarinya.

Dengan menganggap bahwa manfaatnya lebih besar daripada biaya yang diberikan - yang akan menjadi pertanyaan terpisah - tidak sulit untuk melihat mengapa itu diadopsi secara bertahap. Saya tidak berpikir ada satu peristiwa yang menyebabkan ini, meskipun saya pasti akan terbuka untuk dididik tentang ini.

Setidaknya dalam pengalaman saya, awalnya ini sering dilakukan melalui konfigurasi Apache - dan mungkin server web lain juga mendukung ini. Namun, secara konseptual tidak ada alasan kuat mengapa server harus ditugaskan dengan ini. Lagipula, rute itu khusus untuk aplikasi yang sebenarnya, jadi masuk akal untuk mendefinisikannya di sana.

Ini memang berubah secara global, tetapi seperti yang Anda tunjukkan, secara bertahap. Alasan untuk ini hampir pasti sangat sederhana: ide-ide bagus tersebar dari waktu ke waktu. Ini juga mengapa tidak mengejutkan bahwa perubahan terjadi secara global. Bukannya semua orang berkumpul dan memutuskan untuk melakukannya dengan cara ini. Sebaliknya, setiap proyek mengadaptasi pendekatan ini ketika mereka berpikir itu akan bermanfaat (dan proyek yang tidak mendukungnya akhirnya menghilang).

dua kali kamu
sumber
1

RFC sudah membangun konsep dari bawah ke atas, dengan URI (yang tidak melampirkan semantik ke bagian lokal), dan URL sebagai kasus khusus yang memperkenalkan semantik mirip jalur untuk memungkinkan dokumen HTML menggunakan tautan relatif ke dokumen URL dasar.

Implementasi yang jelas adalah memetakan bagian lokal URL secara langsung ke sistem file, jadi inilah yang dilakukan pengaturan sederhana - apakah Anda menggunakan basis data relasional khusus untuk mencari dokumen, atau memanfaatkan kunci overhead rendah yang sangat dioptimalkan. Nilai toko yang sudah Anda miliki tidak masalah ke luar, tetapi tentu saja mempengaruhi struktur biaya Anda untuk melayani dokumen.

Jika Anda memiliki aplikasi web dengan data persisten, struktur biaya itu berubah: Anda selalu memiliki overhead dalam menjalankan aplikasi, dan mengintegrasikan URL decoding ke dalamnya membuat banyak fitur lebih mudah untuk diterapkan, mengurangi biaya.

Simon Richter
sumber
1

Pada awalnya, URL dipetakan langsung ke jalur file di server karena mudah, dan tidak ada cara lain untuk melakukannya, bukan? Jika saya meminta /path/to/index.php, saya akan /path/to/index.phpmulai dari direktori root situs web (biasanya bukan dari server itu sendiri, situs web harus disimpan dalam direktori atau subdirektori lebih jauh ke bawah).

Kemudian setelah beberapa tahun, kami mulai belajar tentang menulis ulang, yaitu melayani sumber daya yang berbeda dari yang tampaknya diminta. /request/path/to/index.phpsebenarnya bisa melayani /response/path/to/index.php.

Trik lain adalah bersembunyi index.php. Jika saya meminta /index.php?foo=bar&baz=quxserver dapat merespons dengan bersembunyi index.phpseperti :, /?foo=bar&baz=quxsementara itu sebenarnya melayani index.php.

Langkah berikutnya, yang merupakan langkah penting, adalah kami belajar mengarahkan semua URL ke /index.php. Jadi sekarang, /path/to/some/pagedialihkan ke /index.php?path/to/some/page. Ini agak rumit, karena biasanya setiap slash mewakili subdirektori baru, tetapi dalam hal ini server web dikonfigurasi untuk mengirim path sebagai parameter, alih-alih melihatnya.

Sekarang kita sudah memiliki ini, kita perlu cara berpikir yang sama sekali berbeda tentang bagaimana situs web diorganisasikan. Sebelumnya, itu adalah koleksi longgar berbagai halaman. Sekarang, semuanya dialihkan melalui halaman entri tunggal. Ini membuat situs jauh lebih rumit, tetapi memberikan peluang yang sebelumnya tidak tersedia, seperti otentikasi pengguna di seluruh situs, penerapan header, footer dan gaya yang seragam, dll.

Secara efektif mengubah ratusan atau ribuan situs web aplikasi Anda (jika Anda menganggap setiap file sebagai aplikasi sendiri) menjadi aplikasi tunggal, jauh lebih rumit tetapi jauh lebih konsisten.

Ini adalah lompatan besar, karena Anda tidak bisa lagi mengatakan kode apa yang akan dieksekusi hanya dengan melihat URL. Anda sekarang harus memiliki pemahaman yang mendalam tentang bagaimana kerangka kerja Anda menerjemahkan jalur URL menjadi jalur kode, dan meskipun ada kesamaan di antara kerangka kerja tersebut, sebagian besar cukup berbeda sehingga Anda memerlukan sedikit pengetahuan untuk dapat bekerja dengan kode tersebut.

Singkatnya, itu adalah evolusi penemuan secara bertahap, bukan lompatan tiba-tiba, dan setiap pengembang harus melalui perjalanan penemuan yang sama. Kurva pembelajaran cukup curam, kecuali Anda dapat memahami konsep abstrak dengan sangat cepat.

CJ Dennis
sumber
-1

Sebagai webdev lama, saya pikir munculnya kontrol navigasi-kurang sejarah ( history.pushState()) sekitar waktu HTML5 membuat ini praktis. Sebelum itu, Anda harus memuat ulang halaman untuk memperbarui bilah URL, kecuali jika Anda hanya memperbarui fragmen ( /path#fragment). Fragmen ini tidak terlihat oleh server (tidak dirutekan), jadi satu-satunya cara untuk menyegarkan atau menandai halaman dinamis adalah melalui JavaScript.

Ini memiliki implikasi besar untuk SEO, dan mengarahkan google untuk mengembangkan skema "hashbang" yang jarang digunakan yang membutuhkan pemetaan sisi server dari hash dinamis ke URL fisik. Ini sulit dan tidak universal di antara robot, memimpin aksioma (salah): "laba-laba tidak dapat merayapi konten ajax". Tetapi manfaat dari konten ajax nyata: coba gunakan google maps tanpa JS misalnya.

Solusinya adalah cara untuk memperbarui bilah URL dengan nilai yang dapat dicerminkan di server (memungkinkan bookmark dan penyegaran JS-kurang), TANPA memuat ulang halaman. Setelah kemampuan ini tersedia, pengembang dapat "menavigasi" situs hanya dengan memperbarui "bagian konten utama", bilah URL, dan remah roti. Ini berarti bahwa semua JS + CSS tidak perlu diambil ulang + diuraikan, memungkinkan transfer halaman ke halaman yang JAUH lebih cepat.

Dandavis
sumber