- Aplikasi frontend yang kompleks berawal dari cache respons API, lalu memikul indeks manual hingga invalidasi cache, sehingga kondisinya mendekati implementasi ulang database kecil di setiap proyek
- Dalam framework deklaratif seperti React, agar API tidak dipanggil di setiap render, cache ditempatkan di state lokal atau lapisan Redux, dan lapisan ini lambat laun mengambil peran sebagai penyimpanan pusat
- Penyimpanan berbasis ID dan struktur kueri berdasarkan tanggal membuat pencarian lebih cepat, tetapi menjaga konsistensi di antara beberapa struktur seperti
CACHEdanENTRIES_BY_DATEmenambah beban pengujian dan code review - Perubahan optimistis langsung memperbarui UI sebelum respons server sehingga meningkatkan kecepatan yang dirasakan, tetapi membawa biaya konsistensi seperti duplikasi logika klien-server, pelacakan perubahan yang sedang berjalan, rollback saat error, dan rekonsiliasi setelah aplikasi dijalankan ulang
- SQLSync berupaya menyediakan cache yang tahan lama, indeks, constraint, perubahan optimistis, dan query reaktif di dalam stack frontend melalui database lokal berbasis SQLite dan sinkronisasi mirip Git Rebase
Proses cache frontend berkembang menjadi database
- Pengelolaan data frontend dapat dimulai dari cache sederhana yang menyimpan respons API ke variabel lokal
- Framework deklaratif seperti React me-render ulang tree berkali-kali selama interaksi pengguna
- Agar tidak mengirim request API di setiap render, hasil request atau error dapat disimpan dalam state komponen dengan
useStatedanuseEffect - Contoh disederhanakan demi kejelasan, dan dalam praktiknya ada juga pilihan untuk memakai library API yang sudah teruji
- Cache dapat dipindahkan ke lapisan yang lebih tinggi dalam tree UI atau ke luar UI
- Redux adalah library manajemen state React yang menyatukan state dan mengoordinasikan perubahan atomik dari waktu ke waktu
- Ekosistem Redux telah berkembang dengan tool dan pola untuk mengelola caching data API
- Cara penggunaan seperti ini bertujuan memusatkan logika cache, mengoordinasikan pembaruan, dan berbagi hasil cache antar-komponen
- Semakin besar lapisan caching, semakin ia menyerupai sistem penyimpanan pusat yang menangani data secara efisien sesuai mesin rendering dan aksi pengguna
Indeks manual dan beban konsistensi
- Di frontend pun, data yang diterima dari server dapat disimpan dalam objek dengan ID sebagai key agar cepat dicari dan diubah
- Pada aplikasi yang memakai REST API, data sering dibaca secara batch lalu objek yang dibutuhkan diperkaya lagi
- Menyimpan objek per ID memudahkan penggabungan hasil API ke cache
- Struktur ini dioptimalkan untuk operasi create, read, update, dan delete berbasis ID
- Filtering yang harus menelusuri banyak item mendorong pembuatan indeks terpisah untuk menghindari pemeriksaan seluruh entri
- Jika membuat struktur
ENTRIES_BY_DATEberdasarkan bagian tahun/bulan/tanggal daricreatedAt, entri pada tanggal tertentu dapat ditemukan dengan cepat - Sebagai gantinya, konsistensi antara
CACHEdanENTRIES_BY_DATEharus terus dijaga - Kueri rentang tanggal membutuhkan beberapa kali akses, dan array yang diurutkan berdasarkan tanggal dengan logika kueri dan pembaruan yang lebih kompleks bisa menjadi struktur yang lebih baik
- Jika membuat struktur
- Semakin banyak indeks, setiap indeks membutuhkan logika pembuatan, pembaruan, dan kueri
- Verifikasi kebenaran membesar menjadi beban pengujian dan code review
- Jika penghapusan atau pembaruan terlewat di satu indeks, bug yang sulit ditemukan dapat muncul
- Lebih banyak waktu dapat tersita untuk infrastruktur yang mengelola kompleksitas ini daripada untuk fitur aplikasi baru
- Indeks database sungguhan jauh lebih kompleks daripada sekadar menyimpan data dalam bentuk lain
- Di dalamnya termasuk elemen seperti pengumpulan statistik, manajemen versi data, kontrol transaksi, locking, dan interaksi dengan optimisasi kueri
Masalah konsistensi yang ditambahkan oleh perubahan optimistis
- Perubahan optimistis terlebih dahulu menyimulasikan efek operasi tertentu secara lokal sebelum respons server datang
- UI dapat bereaksi seketika seolah tidak ada latensi jaringan
- Jika server mengambil keputusan berbeda dari perkiraan atau terjadi error, UI mungkin perlu me-rollback perubahan dan meminta pengguna memperbaiki masalah
- Ini menjadi tool yang kuat ketika klien dapat memprediksi hasil server dengan baik, error dapat ditangani di klien, dan logikanya tersinkronisasi erat
- Update optimistis biasanya mengalir dalam empat tahap
- UI memicu operasi tulis
- Dengan asumsi server akan menyetujuinya, perubahan diterapkan ke cache lokal dan UI langsung di-render ulang
- Operasi perubahan dikirim ke server secara asinkron
- Respons server digabungkan ke cache lokal untuk menimpa perubahan optimistis sebelumnya, lalu UI di-render ulang jika diperlukan
- Untuk menjaga konsistensi dengan server, beberapa beban muncul
- Logika harus diduplikasi di klien dan server agar hasil dapat diprediksi
- Setiap perubahan yang sedang berjalan harus dilacak untuk menangani error asinkron atau ketidaksesuaian server
- Demi pengalaman pengguna yang lebih baik, bagian cache optimistis mungkin perlu dibuat tahan lama agar perubahan dapat direkonsiliasi setelah aplikasi dijalankan ulang
- Proses ini meningkatkan waktu pengembangan dan biaya verifikasi kebenaran, sehingga pengelolaan data dapat mendahului pengembangan nilai bagi pengguna atau fitur pembeda
Kompleksitas invalidasi cache rekursif
- Dalam aplikasi dengan banyak data, informasi yang sama muncul di berbagai lokasi dalam cache
- Contoh cache menyimpan
projects,tasks, danusersbersama-sama - Setelah tugas selesai, beberapa bagian seperti progres proyek, tugas yang ditugaskan ke pengguna, dan informasi tugas baru dapat terdampak
- Contoh cache menyimpan
- Untuk menyelaraskan cache dengan server setelah tugas selesai, beberapa round trip mungkin diperlukan
- Memberi tahu server bahwa tugas telah selesai
- Me-refresh proyek karena progres proyek berubah
- Memeriksa apakah ada penugasan tugas baru
- Jika ada penugasan baru, mengambil tugas tersebut
- API yang lebih kompleks dapat mengurangi jumlah round trip, tetapi hasilnya tetap membuat API atau logika klien terikat dengan model data yang mendasari
- GraphQL adalah salah satu pendekatan untuk masalah ini, tetapi bukan solusi lengkap
- Struktur yang mengharuskan UI mengetahui bagian cache mana yang terkait pada setiap perubahan menjadi rapuh seiring skala bertambah
- Relasi dan agregasi data dapat memengaruhi banyak bagian cache lokal
- Ketika tim engineering membesar, masalahnya dapat melintasi batas tim dan terasa seperti variabel global mutable dalam proyek software besar
- Jika digabungkan dengan perubahan optimistis, klien akan mereplikasi lebih banyak logika backend untuk memprediksi perubahan server
- Dalam contoh, klien mungkin mencoba menghapus task 1 dari user 1 dan menghitung progres sebagai rasio baru menggunakan total jumlah tugas
- Semakin nested perubahan yang dibuat agar dapat diprediksi secara lokal, semakin banyak stack backend yang diduplikasi oleh klien
Stack database frontend yang diusulkan SQLSync
- SQLSync adalah stack database yang dioptimalkan untuk frontend dan dibangun di atas SQLite
- Contoh aplikasi Todo mengimplementasikan seluruh lapisan data dengan 60 baris Rust dan beberapa query SQL yang tersebar di komponen
- SQLSync menyediakan cache tahan lama, indeks/constraint/trigger/optimisasi kueri SQLite, perubahan optimistis, invalidasi cache cerdas, dan query reaktif
- Data lokal disimpan dalam satu atau lebih database SQLite
- Indeks dapat dibuat dengan mudah dan otomatis tersinkronisasi dengan data
- Database dapat otomatis menggunakan indeks untuk mempercepat kueri seperti di backend
- SQL dapat mengekspresikan pengambilan data yang kompleks, dan fitur seperti triggers, foreign keys, constraints, serta full-text search juga dapat digunakan
- Perubahan optimistis ditangani dengan reducer
- Strukturnya mirip dengan konsep inti Redux
- Reducer dapat ditulis dalam bahasa apa pun yang dapat dikompilasi ke WebAssembly
- SQLSync menjalankan perubahan secara optimistis di klien dan menjalankannya di server dalam urutan yang konsisten secara global
- Setelah itu, klien tersinkronisasi dengan server melalui operasi yang mirip Git Rebase
- Arsitektur ini memiliki keunggulan karena menghilangkan kebutuhan invalidasi cache rekursif
- Semua logika perubahan data ditulis dalam reducer yang mudah dibagikan di klien dan server
- Semua perubahan data yang terjadi selama perubahan tersebut otomatis terlihat
- Karena sinkronisasi bekerja seperti Git Rebase, bahkan jika server membuat perubahan berbeda dari klien, klien dijamin mencapai hasil konsisten yang sama
Pekerjaan terkait
- “Building data-centric apps with a reactive relational database” dari Riffle membahas ide menyimpan seluruh state aplikasi, termasuk state UI, dalam satu database reaktif
- Query reaktif menyediakan model berpikir yang rapi dan cocok dengan sistem deklaratif seperti React
- Masalah pengembangan aplikasi klien diselesaikan dengan gagasan dari komunitas database
- Membahas manfaat memodelkan state dengan model data relasional dan indeks sungguhan
- Stepan dari Instant.db menulis dua artikel tentang database di dalam browser
- Database in the Browser, a Spec
- A Graph-Based Firebase
- Kedua artikel membahas masalah serupa dengan lebih berfokus pada hubungan antara stack frontend dan backend, serta menjelaskan motivasi di balik pembuatan Instant.db sebagai penerus berbasis graf dari Firebase
- CR-SQLite dari Matt Wonlaw adalah ekstensi SQLite
- Menggunakan conflict-free replicated data type (CRDT) dan log peristiwa berurutan kausal untuk menggabungkan data secara konsisten
- Memungkinkan aplikasi peer-to-peer menyimpan data di SQLite dan berkolaborasi tanpa koordinator pusat
- Ini juga merupakan contoh menjalankan SQLite di browser
- Matt Wonlaw juga sedang mengeksplorasi gagasan terkait
- incremental computation
- Peningkatan kegunaan SQL melalui typed-sql
1 komentar
Pendapat di Hacker News
Saya cukup mengenal proyek ini, dan pembuatnya teman saya, jadi saya akan coba mengajaknya ke sini untuk menjawab pertanyaan
Dia adalah arsitek basis data yang berpengalaman. Dengan SQLsync, ia membuat developer frontend bisa melakukan query dan update ke basis data jarak jauh seolah-olah basis data itu sepenuhnya berada di dalam browser. Pada praktiknya memang hampir begitu, dan berkat WASM, seluruh basis data SQLite bisa dikirim ke browser. Intinya ada pada algoritme reaktif yang cerdas tetapi sederhana untuk sinkronisasi di banyak klien
Kalau kita menganggap sebagian besar pekerjaan pengembangan adalah sinkronisasi data, React dan REST API juga bisa dilihat sebagai semacam prosedur sinkronisasi, dan pendekatan ini membuka kemungkinan baru. Tidak perlu lagi membuat basis data kustom yang aneh berupa tree objek yang diambil dari API lalu di-cache; cukup gunakan kekuatan basis data relasional untuk langsung melakukan update dan query secara lokal
Namun di perusahaan web tradisional, ini sulit diadopsi karena adanya tim backend/frontend yang terspesialisasi. Ini seperti membuang lapisan basis data, backend, transport, dan autentikasi lalu menggantinya dengan satu sistem blok; kebanyakan arsitek sistem berasal dari backend sehingga tidak terlalu memahami masalah ini. Karena menyentuh kedua sisi secara mendalam, pendekatan ini tidak cocok dengan sistem yang sudah ada, dan pada akhirnya lebih cocok untuk pengembangan baru. Backend-nya juga bukan layanan AWS atau Azure dan tidak ramah Lambda, jadi sebagian besar tipe arsitek yang saya temui kemungkinan tidak akan mau menyentuhnya
Cara ini sampai batas tertentu sudah ada dengan teknologi lama, CouchDB+PouchDB. Untuk sebagian penggunaan, itu cukup cocok, tetapi sistem query-nya tidak ideal, dan cara autentikasi serta penentuan cakupan datanya terasa asing bagi kebanyakan orang. Kasus termudah adalah ketika data sepenuhnya dimiliki satu pengguna dan model basis data per pengguna bisa dipakai apa adanya. Jika data dipartisi kuat dengan CRDT, masalah konflik juga jauh berkurang
Namun ada masalah skalabilitas. Ketika 10 ribu hingga 100 ribu pengguna terhubung, kebutuhan CPU CouchDB sangat tinggi; teknologinya juga sudah tua, meski masih dipelihara. Dari sisi desain sistem, begitu mulai berbagi data antar pengguna, kompleksitas meningkat tajam, sehingga alih-alih menyelesaikan kompleksitas, kita hanya memindahkan lokasinya, dan kecocokannya pun menurun
Pendekatan ini tampaknya juga mengincar tujuan yang sama, tetapi kemungkinan besar akan mengalami masalah skalabilitas serupa. Saya menantikan bagaimana ini berkembang ke depan; ini terlihat seperti langkah awal
Saya ingat dulu Chrome pernah mencoba memasukkan basis data SQL secara harfiah ke browser, tetapi tidak berjalan baik, lalu localStorage menjadi arus utama. Saya tidak bermaksud meremehkan kegunaannya; biasanya saya cenderung memilih apa yang disediakan browser. Saya sangat menantikan kemungkinan membawa WASM, beserta ekosistemnya yang makin matang atau fiturnya yang bertambah, ke browser
Perusahaan tempat saya bekerja dulu menggunakan software manajemen proyek yang memiliki mekanisme check-out/check-in untuk perubahan. Saat sebuah proyek di-check-out, salinan untuk diedit secara lokal diunduh; saat di-check-in, salinan itu diunggah kembali ke server. Selama status check-out, proyek dikunci. Di era aplikasi dengan update live, semua orang merasa itu cara yang ketinggalan zaman
Namun setelah 10 tahun membuat web app SPA, cara sinkronisasi data itu terasa seperti mendahului zamannya
Pada akhirnya, ini bermuara pada apakah kita bisa mengimplementasikan prosedur yang secara konsisten menyelesaikan ketidaksesuaian di antara beberapa update bersamaan. Ada kasus yang memungkinkan dan ada yang tidak, dan itu lebih bergantung pada aturan bisnis daripada kemampuan teknis
Jika berdasarkan aturan bisnis kita tidak bisa mengimplementasikan mekanisme penyelesaian, maka meski secara teknis mampu mendukung update bersamaan, tetap diperlukan penguncian agar hanya satu update terjadi pada satu waktu
Namun sulit meyakinkan orang bahwa inilah yang sebenarnya diinginkan. Mudah sekali terjebak dalam ilusi besar bahwa semuanya harus selalu tersedia, padahal dalam kenyataan biasanya satu orang membuat perubahan pada satu waktu, dan jika dua orang atau lebih harus bekerja, mereka sering kali tetap perlu berbicara atau berkomunikasi untuk menyelaraskan
Bahkan dalam pengembangan yang sepenuhnya terdistribusi seperti Git, konflik tidak bisa diselesaikan otomatis secara ajaib. Untuk memilih perubahan yang benar, kita tetap perlu berkomunikasi dengan orang lain dan memahami konteksnya
Beberapa hal membutuhkan solusi yang sudah teruji
Saya ingat dulu saat perusahaan pindah dari RCS ke CVS, salah satu rekan kerja kesal karena CVS tidak mendukung check-out dengan penguncian
https://en.wikipedia.org/wiki/Concurrent_Versions_System
Saya rasa strategi penguncian pemilik tunggal juga bisa disimulasikan dengan SQLSync. Namun tergantung aplikasinya, itu mungkin tidak diperlukan. Jika tujuannya adalah bekerja offline lalu menggabungkan perubahan saat siap, SQLSync menyediakan pola ini secara bawaan. Jika tujuannya hanya memperbolehkan satu klien melakukan perubahan, diperlukan pola penguncian terpusat, dan kemungkinan ini juga bisa dikoordinasikan melalui SQLSync
Di sini, prinsip “apa yang diukur akan dikelola” terkait dengan kekeliruan biaya hangus
Masalah sebenarnya pada database adalah kompleksitas. Tiap fitur secara terpisah umumnya aman, tetapi saat reliabilitas, caching, dan indeks saling berinteraksi, kompleksitasnya meledak, dan biasanya mengimplementasikan DB khusus domain tidak masuk akal
Namun ketika perusahaan menyadari bahwa mereka sudah berinvestasi dan menggelontorkan banyak sumber daya untuk mengimplementasikan ketiga fitur itu, secara politis sulit untuk menyarankan agar semuanya dicabut, dan biaya nyata untuk menghapus utang teknis sekaligus juga besar
Menurut saya masalah sebenarnya adalah sintaks SQL. Jika pengalaman memakai database relasional dasar terasa senyaman sintaks bergaya C yang familier, bukan bahasa Inggris patah-patah, insentif untuk memakai DB alih-alih membuat sendiri akan lebih besar. Database NoSQL adalah langkah bagus ke arah itu, tetapi umumnya terlalu berfokus pada big data ketimbang kegunaan sehari-hari. Yang seperti Redis sudah mapan dan cukup bagus
Membuat SQL mudah dijalankan adalah pendekatan yang masuk akal, tetapi database yang bagus, misalnya Postgres yang saya suka, memakai SQL sebagai bahasa bawaan, sehingga sulit mendapatkan efisiensi tanpa memakai bahasa itu. Kita benar-benar butuh database seperti PostgresPostSQL yang mereplikasi Postgres secara sempurna, tetapi parser bawaannya mendukung bahasa dengan sintaks yang bagus
Dalam pemrograman umum, puluhan bahasa digunakan dan terus berevolusi. Bahkan JavaScript, yang sulit diubah karena dijalankan browser dan kita tidak bisa mengendalikan browser pengguna, terus berevolusi lewat transpiler dan WebAssembly
Namun di database, pada praktiknya hanya ada satu SQL. Ada alternatif, tetapi dari sisi penggunaan tidak ada yang mendekati SQL. Mungkin saja SQL memang tidak seburuk itu
Alasannya mungkin karena model relasional memang sangat bagus. Upaya untuk keluar dari sini kemungkinan besar hanya berhasil di ceruk tertentu. Gaya deklaratif juga sangat bagus, dan keluar dari sana pun sulit meraih keberhasilan besar. Pada akhirnya, jika yang dibuat hanya SQL dengan sintaks berbeda, bagi kebanyakan orang peningkatannya tidak cukup besar untuk mengganti cara kerja
Aplikasi yang ditulis untuk API ini dapat mengimplementasikan DB SQL. Cukup parsing SQL, lalu implementasikan perencana kueri yang mengeluarkan rencana kueri yang sesuai dengan API ini
Saya penulisnya. Saya baru sempat membaca sekilas sebagian besar pertanyaan, dan akan terus memeriksa secara berkala apakah ada pertanyaan yang terlewat. Saya juga penasaran apakah ada yang sudah membuat cara yang lebih baik untuk melacak diskusi HN
Saya sangat senang dengan diskusi sejauh ini. Tulisan pertama lebih berfokus pada motivasi rekayasa frontend yang membuat saya membangun SQLSync, daripada bagaimana SQLSync bekerja secara konkret. Saya berencana membahas cara kerjanya di tulisan berikutnya
Jangan sampai pengguna memiliki model mental yang dapat dirusak oleh realitas secara parah, atau tanpa terlihat
Saya khawatir pendekatan menyinkronkan database alih-alih model client-server adalah salah satu kasus seperti itu. Mekanisme sinkronisasinya bisa saja langsung meleleh, atau mungkin ada asumsi-asumsi mendalam yang tidak terpenuhi
Jika membutuhkan UI cepat, rasanya lebih aman membuat sekumpulan primitif CRDT dan memakainya, sementara sisanya tetap berupa pengiriman formulir
Sinkronisasi state antara client dan server adalah masalah terkutuk
Dengan menerima sedikit pengorbanan pada pengalaman pengguna dan kembali ke pendekatan yang lebih dekat dengan model PHP/server-side rendering, masalah ini bisa dihindari sepenuhnya. SPA memang bagus, tetapi pengiriman formulir multipart juga masih berfungsi. Dengan JavaScript yang sangat sedikit pun, sebagian besar sisi kasar yang tersisa bisa dihaluskan
Pada produk web terbaru, state di sisi client hanya klaim autentikasi dari IdP pihak ketiga, ID sesi pihak pertama di parameter kueri, dan dokumen saat ini. Sejujurnya saya juga tidak tahu yang pertama disimpan di mana. Itu masalah Microsoft, bukan masalah kami. Semua state lainnya ada di server
Kami memperlakukan client seperti terminal bodoh yang hanya mencetak input sepanjang hari. Kami juga tidak memakai cookie pihak pertama atau local storage. Pendekatan ini sangat memperbaiki pengalaman pengembangan untuk target iOS/Safari
Jadi saya ingin bertanya, pengalaman apa sebenarnya yang ingin diberikan, dan mengapa itu cukup membenarkan pemisahan state client dan server
Referensi: https://news.ycombinator.com/item?id=37584049
Tampaknya pendekatan berbasis SQLite yang offline/local-first sedang hangat belakangan ini. Ini yang ketiga saya baca minggu ini, dan kelihatannya bagus
Tapi bagaimana dibandingkan dengan ElectricSQLhttps://electric-sql.com/ dan PowerSynchttps://powersync.com/?
ElectricSQL dan PowerSync sama-sama menangani masalah yang sangat sulit, yaitu replikasi parsial. Mereka mencoba membuat solusi umum agar database pusat tradisional dapat menyinkronkan dua arah hanya data yang dibutuhkan klien, sambil tetap mendukung perubahan optimistis beserta penanganan konsistensi/konflik yang mengikutinya
Kekurangannya adalah kompleksitas implementasi. Kita harus melacak dengan tepat subset mana dari keseluruhan database yang dimiliki tiap klien, supaya perubahan bisa didorong hanya ke subset tersebut. Selain itu, untuk menentukan subset mana dari status database yang akan diunduh, dibutuhkan DSL baru, yang juga harus dipelajari dan dioptimalkan. Meski begitu, menyenangkan melihat mereka memecahkan masalah yang sangat sulit ini, dan saat SQLSync siap mendukung replikasi parsial, praktik terbaiknya kemungkinan sudah tersusun
Sebaliknya, SQLSync saat ini hanya mendukung sinkronisasi seluruh DB. Semua klien melihat tampilan yang konsisten atas seluruh database. Bisa langsung muncul pertanyaan apakah ini ide yang baik, dan memang tidak cocok untuk sebagian aplikasi. Namun jika membayangkan aplikasi keuangan pribadi, tujuan utamanya adalah sinkronisasi antarperangkat, backup cloud, kemampuan offline, dan semacamnya, sehingga menyimpan seluruh DB di semua perangkat justru bisa menjadi cara yang diinginkan. Model data berorientasi dokumen seperti Airtable juga bisa menjadi contoh. Jika tiap Airtable dijadikan database terpisah, klien bisa mengelola sendiri tabel mana yang perlu diperhatikan
Dengan berfokus pada sinkronisasi seluruh DB, mesin sinkronisasinya menjadi jauh lebih sederhana dibandingkan solusi yang mendukung replikasi parsial. Salah satu keuntungannya adalah backend bisa sangat ringan. Demo saat ini (https://sqlsync-todo.pages.dev) berjalan sepenuhnya di dalam Cloudflare Durable Objects dengan penggunaan storage dan waktu CPU yang sangat kecil
Masih banyak yang harus dilakukan agar SQLSync dapat memungkinkan use case seperti ini, dan statusnya masih lebih dekat ke prototipe, tetapi pengujian awalnya sangat positif
Dalam aplikasi multitenant besar dengan dataset individual yang relatif kecil, saya beberapa kali berpikir, “bagaimana kalau database-nya langsung saja dikirim ke klien?” Saya tidak mendalaminya karena terlihat seperti pola arsitektur terkutuk yang cukup jauh menyimpang dari standar. Akan menyenangkan kalau ternyata saya salah
Masih banyak yang harus dilakukan untuk membuktikannya dengan benar, tetapi saya cukup antusias untuk terus mendorongnya dan melihat ke mana arahnya
Ini terlihat seperti salah satu masalah yang akan sepenuhnya hilang jika kita meninggalkan SPA
Dengan solusi keluarga Hotwire atau htmx, kueri hanyalah kueri server, dan masalah membuat kueri semacam itu cepat sudah jauh lebih dipahami
Saya memakainya bersama ocaml + web components, dan itu pengalaman produktivitas 10/10. Cukup punya satu build tool yang kompilasinya lebih cepat daripada kedipan mata, dan karena tidak perlu wiring mapping JSON antara frontend dan backend, rasanya benar-benar produktif
Secara pribadi saya lebih suka InertiaJs https://inertiajs.com. Itu semacam sistem frontend router yang menyinkronkan state dengan server memakai “cara lama”
Apalagi jika produknya harus tetap berjalan di wilayah dengan internet yang tidak stabil
Saat ini saya sedang menulis artikel yang sangat mirip tentang “database full-stack”. Artikel itu membahas pola banyak aplikasi yang membuat ulang logika backend dan database di kode klien frontend. Solusi yang kami sarankan adalah memilih database yang bisa dijalankan di sisi server maupun klien, lalu menyinkronkannya di antara keduanya
Alasan kami tidak memakai SQLite di produk kami adalah, jujur saja, SQL bukan alat yang cocok untuk melakukan kueri pada data aplikasi. Ia tidak mudah selaras dengan struktur data yang diinginkan di kode klien, dan hampir semua database SQL tidak punya cara untuk berlangganan perubahan kueri tanpa melakukan polling kueri berulang-ulang
Jika Anda menyukai ide menaruh database lengkap di klien dan menginginkan integrasi mendalam dengan TypeScript/JavaScript, silakan lihat https://github.com/aspen-cloud/triplit yang sedang kami buat
https://github.com/cpursley/walex
Saya memakainya dengan cara yang sangat sederhana. Jika data pada tabel dasar berubah, kueri otomatis dijalankan ulang. Ini mungkin tidak seefisien memperbarui hasil secara inkremental, tetapi karena kueri SQLite biasanya sangat cepat, menurut saya itu bukan masalah besar