HTMX dan Pendekatan Aplikasi Berbasis Hypermedia

Foto oleh Florian Olivo on Unsplash
HTMX adalah pustaka JavaScript kecil tanpa dependensi (sekitar 14 KB setelah diminifikasi dan digzip) yang memungkinkan elemen HTML apa pun mengirim permintaan AJAX lewat atribut seperti hx-get dan hx-post. Server merespons dengan fragmen HTML yang ditukar HTMX ke halaman, sehingga Anda membangun aplikasi interaktif dengan JavaScript sisi klien jauh lebih sedikit daripada SPA biasa.
hx-get (serta hx-post/put/patch/delete) menetapkan verb HTTP dan URL permintaan. hx-trigger memilih peristiwa yang memicunya, hx-target adalah selektor CSS untuk tempat respons mendarat, dan hx-swap mengatur cara penyisipannya, misalnya innerHTML untuk mengganti isi atau outerHTML untuk mengganti seluruh elemen.
SPA React menyimpan state aplikasi di peramban dan bertukar JSON dengan server, merender UI di sisi klien. Aplikasi berbasis hypermedia menyimpan state di server dan mengirim HTML yang siap ditampilkan, mengikuti HATEOAS. Hasilnya lebih sedikit kode klien dan alur data lebih sederhana, dengan konsekuensi satu pulang-pergi jaringan per interaksi.
HTMX kesulitan saat sebuah fitur butuh pembaruan UI di setiap interaksi tanpa pulang-pergi, seperti seret real-time atau sel spreadsheet yang saling bergantung, atau saat aplikasi harus berfungsi penuh secara luring. Ia juga tidak mengintegrasikan pustaka komponen khusus framework seperti sistem desain khusus React. Untuk itu, framework sisi klien lebih cocok.
htmx 2.0.0 dirilis pada 17 Juni 2024 tanpa menulis ulang API inti, sehingga sebagian besar kode 1.x tetap berjalan. Ia menghentikan dukungan Internet Explorer, memindahkan ekstensi resmi ke repo tersendiri, dan memperketat nilai baku: pengguliran instan, DELETE mengirim parameter kueri, dan selfRequestsOnly baku menjadi true demi keamanan seasal.

Foto oleh Florian Olivo on Unsplash
Ringkasan Utama
HTMX adalah pustaka JavaScript kecil tanpa dependensi yang memungkinkan elemen HTML apa pun mengirim permintaan AJAX melalui atribut seperti hx-get, hx-post, hx-target, dan hx-swap, lalu menukar fragmen HTML yang dikembalikan ke dalam halaman. Ia menghidupkan kembali model hypermedia, menyimpan state di server dan memangkas kode sisi klien dibanding SPA yang berbicara ke JSON API.
Selama lima belas tahun jawaban baku untuk membuat halaman ini interaktif selalu sama: pakai framework JavaScript, bangun aplikasi sisi klien, dan biarkan ia berbicara ke server lewat JSON API. HTMX menawarkan sesuatu yang lebih tenang. Ia mempertanyakan apakah sebagian besar mesin itu memang perlu ketika peramban sudah tahu cara mengambil URL dan merender HTML.
HTMX adalah pustaka JavaScript kecil tanpa dependensi, sekitar empat belas kilobita setelah diminifikasi dan digzip, yang memperluas HTML sehingga elemen apa pun bisa melakukan hal yang dahulu hanya bisa dilakukan oleh anchor dan form. Alih-alih menulis panggilan fetch dan merekonsiliasi virtual DOM, Anda menambahkan beberapa atribut ke markup dan membiarkan pustaka menangani permintaan, respons, dan penukaran. Saya pernah memakainya untuk menggantikan seluruh layar React dengan segelintir template server, dan hasilnya kode yang lebih sedikit dan lebih jarang rusak.
Model pikirnya adalah generalisasi dari tautan biasa. Sebuah anchor normal mengirim permintaan GET saat diklik dan mengganti seluruh jendela dengan responsnya. HTMX menghapus setiap batasan itu. Elemen apa pun bisa mengirim permintaan, memakai verb HTTP apa pun, dipicu oleh peristiwa apa pun, menargetkan bagian mana pun dari halaman, dan hanya mengganti bagian itu. Dokumentasi resmi menyebutnya sebagai mengakses fitur peramban modern langsung dari HTML alih-alih menggunakan JavaScript.
Empat atribut memikul sebagian besar beban. hx-get, hx-post, hx-put, hx-patch, dan hx-delete menamai verb dan URL. hx-trigger memilih peristiwa yang memicu permintaan, entah klik, input, peristiwa keyboard, atau peristiwa khusus, dengan pengubah seperti jeda debounce. hx-target adalah selektor CSS yang menyatakan ke mana respons harus mendarat. hx-swap menentukan cara mendaratnya: innerHTML mengganti isinya, outerHTML mengganti seluruh elemen, dan ada opsi posisi seperti beforebegin dan afterend.
<!-- Live search: fire a GET as the user types, swap the matching
rows into #results. The server returns HTML, not JSON. -->
<input type="search" name="q"
hx-get="/search"
hx-trigger="input changed delay:300ms, search"
hx-target="#results"
hx-swap="innerHTML" />
<table>
<tbody id="results">
<!-- server responds with just these <tr> rows as an HTML fragment -->
</tbody>
</table>
<!-- Delete a contact: issue DELETE, then remove the whole row -->
<button hx-delete="/contacts/42"
hx-target="closest tr"
hx-swap="outerHTML swap:200ms">
Delete
</button>Contoh di atas merangkai kotak pencarian dan tombol hapus tanpa JavaScript khusus sama sekali. Saat pengguna mengetik, HTMX men-debounce input, mengirim GET ke endpoint pencarian, dan menaruh baris yang dikembalikan ke dalam tabel hasil. Tombol hapus mengirim DELETE dan menghapus baris tabelnya sendiri. Yang krusial, server mengirim kembali fragmen HTML, bukan JSON, sehingga tidak ada template sisi klien yang melakukan perenderan.
Poin terakhir itu adalah keseluruhan filosofinya, bukan sekadar detail implementasi. Aplikasi satu halaman biasanya meninggalkan REST: server mengirim JSON, dan klien memegang state aplikasi serta memutuskan cara merendernya. Aplikasi berbasis hypermedia menyimpan state di server dan mengirim HTML yang sudah mengkodekan apa yang bisa dilakukan pengguna berikutnya, karena tautan dan form itulah aksi yang tersedia. Inilah gagasan web orisinal yang dinamai Roy Fielding sebagai HATEOAS, Hypertext As The Engine Of Application State.
Esai htmx menyebut pola ini sebagai Hypermedia-Driven Application, dan mendefinisikannya lewat dua batasan: ia memakai atribut deklaratif yang tertanam dalam HTML alih-alih skrip imperatif untuk interaktivitas, dan ia berbicara ke server dalam hypermedia, yaitu HTML, alih-alih format non-hypermedia seperti JSON. Skrip masih bisa memperkaya halaman, tetapi ia duduk di atas fondasi HTML alih-alih menggantikannya.
Uji naluri yang berguna: jika Anda bisa menggambarkan sebuah fitur sebagai ketika peristiwa ini terjadi, minta HTML ke server lalu taruh di sini, kemungkinan besar itu fitur HTMX yang baik. Gunakan skrip khusus hanya untuk perilaku yang benar-benar khusus klien seperti animasi, seret-dan-lepas, atau UI optimistis.
HTMX bukan pengganti universal untuk framework front-end, dan dokumentasinya sendiri jujur secara menyegarkan tentang hal itu. Esai tentang kapan memakai hypermedia mendaftar titik-titik manisnya dengan jelas, dan itu memetakan ke sebagian besar perangkat lunak yang benar-benar dibangun kebanyakan tim: layar CRUD, situs konten, dan dasbor alih-alih aplikasi kanvas desain.
Esai yang sama sama jelasnya soal di mana hypermedia kesulitan, dan mengabaikan daftar itu adalah cara tim berakhir melawan alatnya sendiri. Apa pun yang butuh pulang-pergi jaringan per interaksi akan terasa salah, karena menyisipkan permintaan HTTP di antara gerakan tetikus dan pembaruan UI tidak bekerja dengan baik. Aplikasi yang mengutamakan mode luring tidak cocok, sebab pendekatan ini mengasumsikan server yang terjangkau. Antarmuka dengan banyak sel yang saling bergantung, di mana spreadsheet adalah contoh kanoniknya, tidak terurai menjadi fragmen yang bersih. Dan Anda tidak bisa menjatuhkan pustaka komponen yang dibangun untuk framework tertentu, seperti sistem desain khusus React.
Jangan perlakukan HTMX sebagai cara menghindari belajar sisi server. Kompleksitasnya tidak lenyap; ia berpindah. Endpoint Anda kini mengembalikan fragmen HTML, yang berarti komposisi template yang jelas, desain URL yang disiplin, dan penanganan cermat antara respons sebagian dan halaman penuh menjadi lebih penting dari sebelumnya. Tim yang melewatkan itu berakhir dengan kekusutan rute fragmen sekali pakai.
htmx 2.0.0 dirilis pada 17 Juni 2024, dan yang penting ia tidak menulis ulang API inti, sehingga kode yang ditulis untuk 1.x sebagian besar tetap berjalan. Perubahan utamanya bersifat perapian: dukungan untuk Internet Explorer dihentikan, dan semua ekstensi resmi dipindahkan keluar dari repositori inti ke repo mereka sendiri agar bisa diberi versi secara independen. Beberapa nilai baku diperketat, karena pengguliran mulus menjadi instan, permintaan DELETE kini mengirim parameter kueri, dan selfRequestsOnly baku menjadi true sehingga permintaan tetap seasal kecuali Anda memilih keluar. Atribut hx-on lama mendapat sintaks hx-on titik dua yang lebih rapi. Untuk menghindari pemaksaan pemutakhiran bagi siapa pun yang memakai tautan CDN tanpa versi, tim mempertahankan 1.x sebagai tag latest npm selama masa transisi.
| Aspek | HTMX (hypermedia) | SPA + JSON API |
|---|---|---|
| Di mana UI dirender | Di server, dikirim sebagai HTML | Di peramban, dari JSON |
| Di mana state berada | Sebagian besar di server | Terbagi antara klien dan server |
| Format muatan | Fragmen HTML | Data JSON |
| JavaScript sisi klien | Minimal, atribut deklaratif | Framework penuh dan langkah build |
| Paling cocok | CRUD, konten, dasbor | Sangat interaktif, luring, real-time |
Aturan praktis saya setelah mengirim keduanya: pakai HTMX lebih dulu untuk apa pun yang digerakkan server, dan tambahkan front-end yang lebih berat hanya bila sebuah fitur benar-benar butuh state sisi klien yang tidak bisa dibawa pulang-pergi. Jika Anda ingin argumen lengkapnya, para penulis htmx menulis buku gratis, Hypermedia Systems, yang memaparkan pendekatan ini dari ujung ke ujung. Itu kasus terjernih yang pernah saya baca untuk kembali menganggap serius model milik peramban itu sendiri.