3 poin oleh GN⁺ 2023-12-19 | 1 komentar | Bagikan ke WhatsApp
  • Jika fungsi PostgreSQL langsung mengembalikan text/html, Anda dapat membuat aplikasi to-do yang menerima hasil permintaan AJAX dan mengganti sebagian DOM hanya dengan PostgREST dan htmx
  • Contoh ini, tanpa autentikasi, memberikan izin web_anon ke api.todos dan api.todos_id_seq, lalu menambahkan tipe media kustom agar dapat menangani permintaan Accept: text/html
  • Perakitan HTML ditangani oleh fungsi SQL, dan api.sanitize_html, api.html_todo, api.html_all_todos mengurus escape nilai input serta rendering daftar
  • Perilaku antarmuka disusun dengan hx-post, hx-get, hx-target, hx-trigger, hx-vals, hx-headers, dan HTML respons menggantikan #todo-list-area atau area edit individual
  • Konfigurasi ini lebih merupakan proof of concept, dan di sisi PostgREST sedang dikerjakan plmustache untuk meningkatkan penanganan HTML

Peran PostgREST dan htmx

  • PostgREST mengembalikan konten HTML, dan htmx menggunakan HTML yang diterima dari hasil permintaan AJAX untuk mengganti elemen di dalam DOM
  • Karena htmx mengharapkan respons HTML, alur di mana server mengembalikan fragmen HTML alih-alih JSON sangat cocok dengannya
  • Contoh ini adalah proof of concept yang menunjukkan konfigurasi yang mungkin saat kedua teknologi digunakan bersama
  • PostgREST sedang mengerjakan plmustache untuk lebih meningkatkan aspek pemrosesan HTML

Pengaturan awal aplikasi to-do

  • Contoh ini adalah aplikasi to-do berbasis Tutorial 0 - Get it Running
  • Untuk penyederhanaan, autentikasi tidak digunakan dan izin yang diperlukan diberikan kepada pengguna web_anon
    • grant all pada tabel api.todos
    • grant usage, select pada sequence api.todos_id_seq
  • Agar PostgREST mengenali permintaan Accept: text/html dari browser sebagai HTML, perlu ditambahkan handler tipe media
    • Membuat domain "text/html" dari text
    • Dengan pengaturan ini, PostgREST dapat mengembalikan dokumen HTML mentah

Mengembalikan halaman HTML dasar

  • Fungsi api.index() mengembalikan "text/html" dan menghasilkan dokumen HTML dasar
  • Halaman ini menyertakan sumber daya berikut bersama judul PostgREST + HTMX To-Do List
  • Di browser, halaman ini dapat dibuka di http://localhost:3000/rpc/index

Rendering daftar dan menambahkan to-do

  • Tiga fungsi SQL digunakan untuk membuat daftar to-do yang ada dalam bentuk HTML
    • api.sanitize_html(text): mengganti karakter &, ", >, <, ' dengan entitas HTML
    • api.html_todo(api.todos): memformat satu item to-do menjadi fragmen HTML
    • api.html_all_todos(): menggabungkan semua item menjadi satu string HTML, dan jika tidak ada item, mengembalikan pesan There is nothing else to do.
  • api.html_todo dan api.html_all_todos adalah fungsi internal untuk membuat template daftar dan tidak digunakan langsung sebagai endpoint PostgREST
  • api.add_todo(_task text) menyisipkan to-do baru ke api.todos lalu mengembalikan HTML daftar lengkap yang telah diperbarui
  • api.index() yang diperbarui menyertakan htmx dan formulir input
    • Menempatkan hx-headers='{"Accept": "text/html"}' pada elemen induk agar permintaan htmx turunannya meminta respons HTML
    • Tanpa header ini, PostgREST tidak akan mengenali permintaan sebagai HTML
  • Formulir penambahan to-do bekerja dengan atribut htmx
    • hx-post="/rpc/add_todo": mengirim nilai input _task dengan permintaan POST ke /rpc/add_todo
    • hx-target="#todo-list-area": menaruh HTML respons ke area daftar to-do
    • hx-trigger="submit": mengirim permintaan saat formulir dikirim
    • hx-on="htmx:afterRequest: this.reset()": mengosongkan formulir setelah permintaan selesai
  • Untuk menerapkan fungsi baru dan perubahan, cache skema harus dimuat ulang
  • Setelah itu, Anda dapat memeriksa tampilan daftar dan penambahan to-do baru di http://localhost:3000/rpc/index

Mengedit, menghapus, dan mengubah status selesai

  • api.html_todo diperluas agar setiap item menyertakan UI untuk mengubah status selesai, mengedit, dan menghapus
  • Perubahan status selesai ditangani dengan <form> dan atribut htmx
    • hx-post="/rpc/change_todo_state": mengirim permintaan AJAX POST ke endpoint tersebut
    • hx-vals='{"_id": ..., "_done": ...}': menambahkan parameter permintaan tanpa input tersembunyi
    • hx-trigger="click": menjalankan permintaan saat item diklik
  • Tombol edit mengubah tugas individual menjadi field input
    • hx-get="/rpc/html_editable_task": memanggil endpoint yang mengembalikan input HTML yang dapat diedit
    • hx-target="#todo-edit-area-...": hanya mengganti area tugas individual, bukan seluruh daftar
    • hx-vals menambahkan parameter permintaan GET, dan saat merepresentasikan kolom tabel, operator eq. diperlukan
  • Tombol hapus mengirim permintaan penghapusan to-do terkait dengan hx-post="/rpc/delete_todo"
  • api.html_editable_task(_id int) mengembalikan HTML field input untuk mengedit to-do tertentu
    • Mengirim nama tugas yang diubah dengan hx-post="/rpc/change_todo_task"
    • Memperbarui saat submit atau focus out melalui hx-trigger="submit,focusout"
    • Menyertakan hx-headers='{"Accept": "text/html"}'
  • Semua endpoint perubahan data mengembalikan HTML daftar lengkap setelah perubahan
    • api.change_todo_state(_id int, _done boolean): memperbarui kolom done
    • api.change_todo_task(_id int, _task text): memperbarui kolom task
    • api.delete_todo(_id int): menghapus to-do yang sesuai dengan _id
  • Setelah memuat ulang cache skema, Anda dapat mengedit, menghapus, dan menandai selesai to-do di http://localhost:3000/rpc/index

1 komentar

 
GN⁺ 2023-12-19
Komentar Hacker News
  • PostgREST adalah salah satu proyek open source favorit saya. Saya rasa Supabase bisa menjadi perusahaan bernilai 1 miliar dolar sebagian besar berkat desain PostgREST dan Postgres yang sangat bagus
    Saya tidak tahu bagaimana Supabase mendanai proyek ini, tetapi saya harap skalanya sangat besar. Melihat proyek yang dipakai ratusan perusahaan berpendapatan sebagai dependensi inti tetapi hanya punya 12 sponsor berbayar membuat saya sedih dengan realitas pendanaan open source
    https://www.patreon.com/postgrest/about

    • Karena ini bagian inti dari stack Supabase, seperti yang disebutkan, mereka mempekerjakan lead maintainer Steve agar terutama bisa mengerjakan PostgREST
      https://github.com/steve-chavez
    • Sekarang jadi 13 orang. Meski begitu, tetap baru $1.529 per bulan
    • Saya tidak tahu PostgREST itu bagian dari Supabase. Saya kira Supabase hanyalah produk tiruan yang dibuat dari nol
    • Saya sudah bisa mendengar omongan klise yang selalu muncul dalam situasi seperti ini. “Pengguna tidak punya kewajiban mendukungmu secara finansial”, “kalau tidak suka, seharusnya jangan rilis dengan lisensi permisif” dan sejenisnya
      Karena itu sekarang saya hanya memakai AGPLv3 atau lisensi serupa. Kalau mau dipakai secara komersial, bayarlah 1% dari total pendapatan
  • Sebagai proof of concept ini keren dan implementasinya patut dipuji, tetapi untuk dipelihara pada web app yang tidak sepele ini terlihat seperti mimpi buruk

    • Jelas lebih cocok untuk website atau aplikasi ringan. Meski begitu, dalam cakupan itu masih bisa dimanfaatkan cukup banyak
    • Saat ini saya sedang bereksperimen apakah Sqitch bisa membuat pemeliharaan jadi lebih mudah. Ini masih terasa seperti akal-akalan dan saya masih ragu apakah benar-benar layak dipakai, tetapi tetap menyenangkan dan saya jadi belajar banyak fitur Postgres tingkat lanjut
      https://sqitch.org/
    • Sejujurnya saya penasaran bagian mana yang kalau memakai ini di aplikasi web utama kami tidak akan jadi 100 kali lebih mudah
    • Untuk saat ini saya rasa begitu. Sekarang tinggal perlu cara untuk mengompilasi dan men-deploy route HTMX ke server database sebagai bagian dari proses CI
  • Saya penasaran apakah fitur atau pola pemrograman seperti ini benar-benar baru atau dipakai juga di aplikasi modern
    CouchDB, database dokumen JSON, menyediakan API berbasis HTTP dan punya metode list/detail bawaan yang bisa merespons dalam format apa pun yang bisa dibuat di dalam interpreter JavaScript. Artinya klien bisa langsung memanggil database untuk mendapatkan HTML atau JSON tanpa perlu server
    Tetapi setelah v1 mereka berhenti mengembangkan ke arah itu karena pemeliharaannya menjadi mimpi buruk. Banyak orang mungkin ingat masa-masa “indah” ketika file PHP atau ASP berisi campuran SQL statement dan HTML, dan ini tampaknya tidak jauh berbeda

    • Rasanya seperti generasi baru sedang mempelajari lagi hal-hal yang dulu ditinggalkan karena alasan yang masuk akal
      Sekitar 13 tahun lalu saya sangat menyukai fitur web CouchDB untuk proyek pribadi, tetapi untuk dikelola tim rasanya cukup merepotkan
    • Sulit menyebut ini modern. Oracle sudah punya hal seperti ini lebih dari 25 tahun lalu
  • Satu-satunya aplikasi PostgREST yang pernah saya kerjakan sangat mengerikan. Karena seperti kebanyakan framework “sederhana” semacam ini, ia hanya sederhana sampai kebutuhan menjadi rumit
    Penulis awalnya akhirnya memakai banyak stored procedure di database untuk mendapatkan hasil yang diinginkan, dan itu menimbulkan masalah skalabilitas. Seperti biasa, solusinya adalah kembali ke SQL

    • Kedengarannya tim itu memilih alat yang tidak cocok untuk pekerjaannya. Kalau sebagian besar endpoint punya logika backend yang kompleks, Anda memang tidak seharusnya memakai PostgREST
      PostgREST dibuat untuk aplikasi CRUD, dan banyak aplikasi yang saya temui termasuk kategori itu. Untuk logika backend kustom yang kadang diperlukan, cukup jalankan di server terpisah atau edge function
    • Saya banyak memakai PostGREST, tetapi dengan guardrail yang kuat. Lapisan API yang sebenarnya harus selalu ada, dan menurut saya ini sebaiknya hanya dipakai sebagai alat bantu untuk memudahkan loading dasar
      Seperti semua alat semacam ini, ketika masuk ke kebutuhan dunia nyata, biaya beradaptasi dengan alat itu menjadi lebih buruk daripada hal yang ingin digantikannya, yaitu SQL + bahasa dan framework apa pun. PostGREST sendiri juga sudah makin kompleks, dan fitur tambahan seperti ini malah membuat saya kurang tertarik
    • Bukankah stored procedure pada akhirnya hanyalah SQL dalam bentuk fungsi?
      Sebelum Rails muncul dan membuat semua orang percaya bahwa menaruh logika bisnis di bahasa server-side yang lambat itu ide bagus, orang dulu memang membuat aplikasi seperti ini
  • Ini stack pengembangan web yang sangat rapi. Hanya HTML dan database, tidak perlu backend dan frontend

    • Saya pernah berkunjung ke Compuserve di Ohio pada pertengahan 90-an. Saat web baru mulai muncul, seorang engineer yang saya temui di sana menunjukkan toko musik yang dia bangun dengan mengembalikan HTML dari SQL stored procedure :)
    • Kalau ini terasa keren, mungkin layak juga melihat Omnigres
      https://github.com/omnigres/omnigres
    • Kita sudah pernah melewati jalan ini. Awalnya memang rapi, tetapi tidak bagus untuk pemeliharaan jangka panjang, dukungan, dan pelatihan
      Setelah pesona HTMX memudar, administrator pada masa itu pada akhirnya akan mengakui bahwa semuanya harus ditulis ulang dari awal
    • Backend dan frontend tetap ada. Hanya saja semuanya sekarang kusut langsung di dalam kode database
    • Pada akhirnya kita cuma kembali ke mainframe. Kali ini browser hanyalah terminal
  • Saya pernah memakai PostgREST tanpa HTMX di proyek lama, dan saya terkesan melihat seberapa jauh ini bisa didorong
    HTMX juga tampak cocok, tetapi saya tidak yakin seberapa besar saya ingin memelihara template HTMX di dalam fungsi SQL

    • Sama sekali tidak tertarik. Saya sudah pernah mengalaminya dengan PHP. Pola seperti ini tidak punya fitur penting seperti analisis statis, pengujian lokal, refactoring, atau perubahan besar yang bisa dikirim secara atomik
      Cocok untuk bikin-bikin iseng, tetapi tidak cocok untuk membangun sesuatu yang andal
  • Dari sudut pandang Haskell, PostgREST itu menarik. Karena proyek ini terlihat seperti sesuatu yang terlalu jelas untuk dibuat
    Tetapi justru karena itu ia terasa jenius. Ini ide yang sangat khas Haskell, dan saya suka itu

  • Menurut Anda, alat tambahan apa yang diperlukan agar konsep ini menjadi stack yang mudah dipelihara dengan pengalaman pengguna yang baik, bahkan untuk aplikasi skala menengah hingga besar?

    • Untuk penyajian situs statis menggunakan Astro(https://astro.build), dan untuk komponen sederhana yang berpusat pada data menggunakan PostgREST Htmx
    • Untuk skala menengah hingga besar, saya rasa diperlukan lapisan abstraksi terpisah, yaitu API
      Saya juga pernah mencoba membuat sesuatu yang mirip di atas SQL, dan stack teknologinya adalah lapisan OpenAPI yang diimplementasikan dengan template Jinja SQL dan YML, tetapi tetap saja sepertinya akan saya batasi pada ranah alat internal. Ada di sini: https://jinj.at
  • Show HN terkait: merender HTML dari SQL dengan pg_render
    https://news.ycombinator.com/item?id=38677852

  • Saya ingin mencatat satu pekerjaan agar tidak lupa pada aplikasi ini. Ini pekerjaan saya:
    Dalam kasus ini, kolom task tampaknya tidak disanitasi di mana pun

    • Pada masa lalu yang buruk, view berkomunikasi langsung dengan database sehingga XSS merajalela. Lalu setelah template engine dan model ditempatkan di tengah, masalahnya tampak terselesaikan
      Tapi sekarang karena database menjadi view, apakah XSS muncul lagi? Ini masalah yang bisa dicegah
    • Benar. htmx dengan senang hati akan mengeksekusi skrip tersebut. Demo-nya juga punya bug yang sama: https://github.com/bigskysoftware/htmx/pull/1995/files
    • Ini tampak seperti argumen jerami terhadap dokumen contoh. HTMX hanya menyajikan HTML, dan input tetap harus disanitasi dengan cara apa pun
      HTML bisa dirender dengan bahasa templating apa pun yang melakukan pemrosesan semacam itu