URLPattern menghadirkan pemilihan rute ke platform web

Pendekatan untuk menstandarkan kasus penggunaan pencocokan pola umum.

Latar belakang

Pemilihan rute adalah bagian penting dari setiap aplikasi web. Pada dasarnya, pemilihan rute melibatkan pengambilan URL, penerapan beberapa pencocokan pola atau logika khusus aplikasi lainnya, lalu, biasanya, menampilkan konten web berdasarkan hasilnya. Pemilihan rute dapat diimplementasikan dengan sejumlah cara: terkadang kode yang berjalan di server yang memetakan jalur ke file di disk, atau logika dalam aplikasi satu halaman yang menunggu perubahan pada lokasi saat ini dan membuat bagian DOM yang sesuai untuk ditampilkan.

Meskipun tidak ada satu standar yang pasti, developer web cenderung menggunakan sintaksis umum untuk mengekspresikan pola pemilihan rute URL yang memiliki banyak kesamaan dengan regular expressions, tetapi dengan beberapa tambahan khusus domain seperti token untuk mencocokkan segmen jalur. Framework sisi server populer seperti Express dan Ruby on Rails menggunakan sintaksis ini (atau sesuatu yang sangat mirip), dan developer JavaScript dapat menggunakan modul seperti path-to-regexp atau regexpparam untuk menambahkan logika tersebut ke kode mereka sendiri.

URLPattern adalah tambahan untuk platform web yang dibuat berdasarkan fondasi yang dibuat oleh framework ini. Tujuannya adalah untuk menstandarkan sintaksis pola pemilihan rute, termasuk dukungan untuk karakter pengganti, grup token bernama, grup ekspresi reguler, dan pengubah grup. Instance URLPattern yang dibuat dengan sintaksis ini dapat melakukan tugas pemilihan rute umum, seperti pencocokan dengan URL lengkap atau URL pathname, dan menampilkan informasi tentang pencocokan token dan grup.

Manfaat lain dari penyediaan pencocokan URL secara langsung di platform web adalah sintaksis umum kemudian dapat dibagikan dengan API lain yang juga perlu dicocokkan dengan URL.

Dukungan browser dan polyfill

URLPattern diaktifkan secara default di Chrome dan Edge versi 95 dan yang lebih baru.

Library urlpattern-polyfill menyediakan cara untuk menggunakan antarmuka URLPattern di browser atau lingkungan seperti Node yang tidak memiliki dukungan bawaan. Jika Anda menggunakan polyfill, pastikan Anda menggunakan deteksi fitur untuk memastikan bahwa Anda hanya memuat polyfill jika lingkungan saat ini tidak memiliki dukungan. Jika tidak, Anda akan kehilangan salah satu manfaat utama URLPattern: fakta bahwa lingkungan dukungan tidak perlu mendownload dan mengurai kode tambahan untuk menggunakannya.

if (!(globalThis && 'URLPattern' in globalThis)) {
  // URLPattern is not available, so the polyfill is needed.
}

Kompatibilitas sintaksis

Filosofi panduan untuk URLPattern adalah menghindari penemuan ulang. Jika sudah terbiasa dengan sintaksis pemilihan rute yang digunakan di Express atau Ruby on Rails, Anda tidak perlu mempelajari hal baru. Namun, mengingat sedikit perbedaan antara sintaksis dalam library pemilihan rute populer, sesuatu harus dipilih sebagai sintaksis dasar, dan desainer URLPattern memutuskan untuk menggunakan sintaksis pola dari path-to-regexp (meskipun bukan platform API-nya) sebagai titik awal.

Keputusan ini dibuat setelah konsultasi yang cermat dengan pengelola path-to-regexp saat ini.

Cara terbaik untuk memahami inti sintaksis yang didukung adalah dengan melihat dokumentasi untuk path-to-regexp. Anda dapat membaca dokumentasi yang ditujukan untuk publikasi di MDN di rumah saat ini di GitHub.

Fitur tambahan

Sintaksis URLPattern adalah superset dari yang didukung path-to-regexp, karena URLPattern mendukung fitur yang tidak umum di antara library pemilihan rute: cocok dengan asal, termasuk karakter pengganti di nama host. Sebagian besar library pemilihan rute lainnya hanya menangani pathname, dan terkadang bagian penelusuran atau hash dari URL. Mereka tidak perlu memeriksa bagian asal URL, karena hanya digunakan untuk pemilihan rute dengan origin yang sama dalam aplikasi web mandiri.

Dengan mempertimbangkan origin, kasus penggunaan tambahan dapat dilakukan, seperti me-rutekan permintaan lintas origin di dalam pengendali peristiwa fetch pekerja layanan. Jika hanya merutekan URL dengan origin yang sama, Anda dapat mengabaikan fitur tambahan ini secara efektif dan menggunakan URLPattern seperti library lainnya.

Contoh

Membuat pola

Untuk membuat URLPattern, teruskan konstruktornya, baik string maupun objek yang propertinya berisi info tentang pola yang akan dicocokkan.

Meneruskan objek menawarkan kontrol paling eksplisit atas pola yang akan digunakan untuk mencocokkan setiap komponen URL. Dalam bentuk yang paling panjang, ini dapat terlihat seperti

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
  search: '*',
  hash: '*',
});

Memberikan string kosong untuk properti hanya akan cocok jika bagian URL yang sesuai tidak ditetapkan. Karakter pengganti * akan cocok dengan nilai apa pun untuk bagian URL tertentu.

Konstruktor menawarkan beberapa pintasan untuk penggunaan yang lebih sederhana. Menghapus sepenuhnya search dan hash, atau properti lainnya, sama dengan menyetelnya ke karakter pengganti '*'. Contoh di atas dapat disederhanakan menjadi

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
});

Sebagai pintasan tambahan, semua informasi tentang asal dapat diberikan dalam satu properti, baseURL, yang mengarah ke

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

Semua contoh ini mengasumsikan bahwa kasus penggunaan Anda melibatkan asal yang cocok. Jika Anda hanya tertarik untuk mencocokkan bagian lain URL, tidak termasuk asal (seperti halnya banyak skenario pemilihan rute satu asal "tradisional"), Anda dapat menghapus informasi asal sepenuhnya, dan hanya memberikan beberapa kombinasi properti pathname, search, dan hash. Seperti sebelumnya, properti yang dihilangkan akan diperlakukan seolah-olah ditetapkan ke pola karakter pengganti *.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

Sebagai alternatif untuk meneruskan objek ke konstruktor, Anda dapat memberikan satu atau dua string. Jika satu string disediakan, string tersebut harus mewakili pola URL lengkap, termasuk informasi pola yang digunakan untuk mencocokkan asal. Jika Anda menyediakan dua string, string kedua akan digunakan sebagai baseURL, dan string pertama dianggap relatif terhadap dasar tersebut.

Baik satu string atau dua string yang disediakan, konstruktor URLPattern akan mengurai pola URL lengkap, membaginya menjadi komponen URL, dan memetakan setiap bagian pola yang lebih besar ke komponen yang sesuai. Ini berarti bahwa di bawah, setiap URLPattern yang dibuat dengan string akan direpresentasikan sama seperti URLPattern yang setara yang dibuat dengan objek. Konstruktor string hanyalah pintasan, bagi mereka yang lebih memilih antarmuka yang tidak terlalu panjang.

const p = new URLPattern('https://example.com/foo/:image.jpg?*#*');

Saat menggunakan string untuk membuat URLPattern, ada beberapa peringatan yang perlu diingat.

Menghapus properti saat menggunakan objek untuk membuat URLPattern setara dengan memberikan karakter pengganti * untuk properti tersebut. Saat pola string URL lengkap diurai, jika salah satu komponen URL tidak memiliki nilai, komponen tersebut akan diperlakukan seolah-olah properti komponen ditetapkan ke '', yang hanya akan cocok jika komponen tersebut kosong.

Saat menggunakan string, Anda harus menyertakan karakter pengganti secara eksplisit jika ingin karakter tersebut digunakan dalam URLPattern yang dibuat.

// p1 and p2 are equivalent.
const p1 = new URLPattern('/foo', location.origin);
const p2 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
  search: '',
  hash: '',
});

// p3 and p4 are equivalent.
const p3 = new URLPattern('/foo?*#*', location.origin);
const p4 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
});

Anda juga harus menyadari bahwa mengurai pola string menjadi komponennya berpotensi ambigu. Ada karakter, seperti :, yang ditemukan di URL, tetapi juga memiliki arti khusus dalam sintaksis pencocokan pola. Untuk menghindari ambiguitas ini, konstruktor URLPattern mengasumsikan bahwa salah satu karakter khusus tersebut adalah bagian dari pola, bukan bagian dari URL. Jika Anda ingin karakter ambigu ditafsirkan sebagai bagian dari URL, pastikan untuk meng-escape-nya dengan \` character. For example, the literal URLabout:blankshould be escaped as'about\:blank'` saat diberikan sebagai string.

Menggunakan pola

Setelah membuat URLPattern, Anda memiliki dua opsi untuk menggunakannya. Metode test() dan exec() menggunakan input yang sama dan menggunakan algoritma yang sama untuk memeriksa kecocokan, dan hanya berbeda dalam nilai yang ditampilkan. test() menampilkan true jika ada kecocokan untuk input yang diberikan, dan false jika tidak. exec() menampilkan informasi mendetail tentang kecocokan beserta grup tangkapan, atau null jika tidak ada kecocokan. Contoh berikut menunjukkan penggunaan exec(), tetapi Anda dapat menukar test() dengan salah satunya jika hanya menginginkan nilai hasil boolean sederhana.

Salah satu cara menggunakan metode test() dan exec() adalah dengan meneruskan string. Serupa dengan yang didukung konstruktor, jika satu string diberikan, string tersebut harus berupa URL lengkap, termasuk origin. Jika dua string disediakan, string kedua akan diperlakukan sebagai nilai baseURL, dan string pertama dievaluasi sebagai relatif terhadap dasar tersebut.

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

const result = p.exec('https://example.com/foo/cat.jpg');
// result will contain info about the successful match.
// const result = p.exec('/foo/cat.jpg', 'https://example.com')
// is equivalent, using the baseURL syntax.

const noMatchResult = p.exec('https://example.com/bar');
// noMatchResult will be null.

Atau, Anda dapat meneruskan jenis objek yang sama dengan yang didukung konstruktor, dengan properti yang ditetapkan hanya ke bagian URL yang ingin Anda cocokkan.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

const result = p.exec({pathname: '/foo/:image.jpg'});
// result will contain info about the successful match.

Saat menggunakan exec() pada URLPattern yang berisi karakter pengganti atau token, nilai yang ditampilkan akan memberi Anda informasi tentang nilai yang sesuai di URL input. Hal ini dapat menghemat waktu Anda karena tidak perlu mengurai nilai tersebut sendiri.

const p = new URLPattern({
  hostname: ':subdomain.example.com',
  pathname: '/*/:image.jpg'
});

const result = p.exec('https://imagecdn1.example.com/foo/cat.jpg');
// result.hostname.groups.subdomain will be 'imagecdn1'
// result.pathname.groups[0] will be 'foo', corresponding to *
// result.pathname.groups.image will be 'cat'

Grup anonim dan bernama

Saat meneruskan string URL ke exec(), Anda akan mendapatkan nilai yang menunjukkan bagian mana yang cocok dengan semua grup pola.

Nilai yang ditampilkan memiliki properti yang sesuai dengan komponen URLPattern, seperti pathname. Jadi, jika grup ditentukan sebagai bagian dari bagian pathname dari URLPattern, kecocokan dapat ditemukan di pathname.groups nilai yang ditampilkan. Kecocokan ditampilkan secara berbeda bergantung pada apakah pola yang sesuai adalah grup anonim atau bernama.

Anda dapat menggunakan indeks array untuk mengakses nilai untuk pencocokan pola anonim. Jika ada beberapa pola anonim, indeks 0 akan mewakili nilai yang cocok untuk pola paling kiri, dengan 1 dan indeks lebih lanjut yang digunakan untuk pola berikutnya.

Saat menggunakan grup bernama dalam pola, kecocokan akan ditampilkan sebagai properti yang namanya sesuai dengan setiap nama grup.

Dukungan dan normalisasi Unicode

URLPattern mendukung karakter Unicode dengan beberapa cara.

  • Grup bernama, seperti :café, dapat berisi karakter Unicode. Aturan yang digunakan untuk ID JavaScript yang valid berlaku untuk grup bernama.

  • Teks dalam pola akan otomatis dienkode sesuai dengan aturan yang sama yang digunakan untuk encoding URL komponen tertentu tersebut. Karakter Unicode dalam pathname akan berenkode persen, sehingga pola pathname seperti /café dinormalisasi ke /caf%C3%A9 secara otomatis. Karakter Unicode di hostname otomatis dienkode menggunakan Punycode, bukan enkode persen.

  • Grup ekspresi reguler hanya boleh berisi karakter ASCII. Sintaksis ekspresi reguler mempersulit dan tidak aman untuk mengenkode karakter Unicode secara otomatis dalam grup ini. Jika ingin mencocokkan karakter Unicode dalam grup ekspresi reguler, Anda harus mengenkodenya secara manual, seperti (caf%C3%A9) untuk mencocokkan café.

Selain mengenkode karakter Unicode, URLPattern juga melakukan normalisasi URL. Misalnya, /foo/./bar dalam komponen pathname ditutup ke /foo/bar yang setara.

Jika ragu tentang cara pola input tertentu telah dinormalisasi, periksa instance URLPattern yang dibuat menggunakan DevTools browser Anda.

Menggabungkan semuanya

Demo Glitch yang disematkan di bawah mengilustrasikan kasus penggunaan inti URLPattern di dalam fetch event handler pekerja layanan, yang memetakan pola tertentu ke fungsi asinkron yang dapat menghasilkan respons terhadap permintaan jaringan. Konsep dalam contoh ini juga dapat diterapkan ke skenario pemilihan rute lainnya, baik sisi server maupun sisi klien.

Masukan dan rencana mendatang

Meskipun fungsi dasar untuk URLPattern telah tersedia di Chrome dan Edge, ada penambahan yang direncanakan. Beberapa aspek URLPattern masih dalam pengembangan, dan ada sejumlah pertanyaan terbuka tentang perilaku tertentu yang mungkin masih perlu ditingkatkan. Sebaiknya Anda mencoba URLPattern dan memberikan masukan melalui masalah GitHub.

Dukungan untuk pembuatan template

Library path-to-regexp menyediakan compile() function yang secara efektif membalikkan perilaku pemilihan rute. compile() mengambil pola dan nilai untuk placeholder token, dan menampilkan string untuk jalur URL dengan nilai tersebut diganti.

Kami berharap dapat menambahkannya ke URLPattern di masa mendatang, tetapi hal ini tidak termasuk dalam cakupan rilis awal.

Mengaktifkan fitur platform web mendatang

Dengan asumsi URLPattern menjadi bagian yang mapan dari platform web, fitur lain yang dapat memanfaatkan pemilihan rute atau pencocokan pola dapat dibuat di atas URLPattern sebagai primitif.

Ada diskusi yang sedang berlangsung tentang penggunaan URLPattern untuk fitur yang diusulkan seperti pencocokan pola cakupan pekerja layanan, PWA sebagai pengendali file, dan pramuat spekulatif.

Ucapan terima kasih

Lihat dokumen penjelasan asli untuk mengetahui daftar lengkap pengakuan.