3 puan yazan GN⁺ 2023-12-19 | 1 yorum | WhatsApp'ta paylaş
  • Bir PostgreSQL fonksiyonu doğrudan text/html döndürürse, yalnızca PostgREST ve htmx ile AJAX isteğinin sonucunu alıp DOM’un bir bölümünü değiştiren bir to-do uygulaması yapılabilir
  • Örnekte kimlik doğrulama olmadan web_anon kullanıcısına api.todos ve api.todos_id_seq yetkileri veriliyor; Accept: text/html isteklerini işlemek için özel medya türü ekleniyor
  • HTML birleştirmesini SQL fonksiyonları üstleniyor; api.sanitize_html, api.html_todo, api.html_all_todos giriş değerlerini escape etmeyi ve liste render etmeyi yönetiyor
  • Ekran davranışı hx-post, hx-get, hx-target, hx-trigger, hx-vals, hx-headers ile yapılandırılıyor; dönen HTML #todo-list-area alanının ya da tekil düzenleme alanlarının yerini alıyor
  • Bu yapı daha çok bir kavram kanıtı niteliğinde; PostgREST tarafında HTML işlemeyi iyileştirmek için plmustache üzerinde çalışılıyor

PostgREST ve htmx’in rolleri

  • PostgREST HTML içerik döndürüyor; htmx ise AJAX isteği sonucunda alınan HTML’i DOM içindeki öğeleri değiştirmek için kullanıyor
  • htmx HTML yanıt beklediğinden, sunucunun JSON yerine HTML parçaları döndürdüğü akışla iyi uyuşuyor
  • Örnek, iki teknoloji birlikte kullanıldığında mümkün olan bir yapılandırmayı gösteren bir kavram kanıtı
  • PostgREST, HTML işleme tarafını daha da iyileştirmek için plmustache üzerinde çalışıyor

To-do uygulaması için hazırlık ayarları

  • Örnek, Tutorial 0 - Get it Running temel alınarak yapılan bir to-do uygulaması
  • Basitleştirmek için kimlik doğrulama kullanılmıyor ve web_anon kullanıcısına gerekli yetkiler veriliyor
    • api.todos tablosuna grant all
    • api.todos_id_seq sequence’ına grant usage, select
  • Tarayıcının Accept: text/html isteğini PostgREST’in HTML olarak algılaması için medya türü işleyicisi eklenmesi gerekiyor
    • "text/html" domain’i text olarak oluşturuluyor
    • Bu ayar sayesinde PostgREST ham HTML belgeleri döndürebiliyor

Temel HTML sayfasını döndürme

  • api.index() fonksiyonu "text/html" döndürür ve temel HTML belgesini oluşturur
  • Sayfada PostgREST + HTMX To-Do List başlığıyla birlikte şu kaynaklar yer alır
  • Tarayıcıda bu sayfa http://localhost:3000/rpc/index adresinden açılabilir

Liste render etme ve to-do ekleme

  • Mevcut to-do listesini HTML’e dönüştürmek için üç SQL fonksiyonu kullanılır
    • api.sanitize_html(text): &, ", >, <, ' karakterlerini HTML entity’lerine dönüştürür
    • api.html_todo(api.todos): Tek bir to-do öğesini HTML parçası olarak formatlar
    • api.html_all_todos(): Tüm öğeleri tek bir HTML string’inde birleştirir; öğe yoksa There is nothing else to do. mesajını döndürür
  • api.html_todo ve api.html_all_todos, liste şablonunu oluşturan dahili fonksiyonlardır; doğrudan PostgREST endpoint’i olarak kullanılmaz
  • api.add_todo(_task text), yeni to-do’yu api.todos içine ekledikten sonra güncellenmiş tüm liste HTML’ini döndürür
  • Güncellenmiş api.index() htmx’i ve giriş formunu içerir
    • Üst öğeye hx-headers='{"Accept": "text/html"}' eklenerek alt htmx isteklerinin HTML yanıt istemesi sağlanır
    • Bu header olmazsa PostgREST isteği HTML olarak algılayamaz
  • To-do ekleme formu htmx öznitelikleriyle çalışır
    • hx-post="/rpc/add_todo": _task giriş değerini /rpc/add_todo adresine POST isteği olarak gönderir
    • hx-target="#todo-list-area": Yanıt HTML’ini to-do listesi alanına yerleştirir
    • hx-trigger="submit": Form gönderildiğinde isteği yollar
    • hx-on="htmx:afterRequest: this.reset()": İstek tamamlandıktan sonra formu temizler
  • Yeni fonksiyonların ve değişikliklerin yansıması için şema önbelleğinin yenilenmesi gerekir
  • Ardından http://localhost:3000/rpc/index üzerinden liste gösterimi ve yeni to-do ekleme kontrol edilebilir

Düzenleme, silme ve tamamlanma durumunu değiştirme

  • api.html_todo, her öğeye tamamlanma durumunu değiştirme, düzenleme ve silme arayüzü içerecek şekilde genişletilir
  • Tamamlanma durumu değiştirme <form> ve htmx öznitelikleriyle işlenir
    • hx-post="/rpc/change_todo_state": İlgili endpoint’e AJAX POST isteği gönderir
    • hx-vals='{"_id": ..., "_done": ...}': Gizli input yerine istek parametreleri ekler
    • hx-trigger="click": Öğeye tıklanınca isteği çalıştırır
  • Düzenleme düğmesi tekil görevi bir giriş alanına dönüştürür
    • hx-get="/rpc/html_editable_task": Düzenlenebilir HTML input döndüren endpoint’i çağırır
    • hx-target="#todo-edit-area-...": Tüm liste yerine yalnızca tekil görev alanını değiştirir
    • hx-vals, GET istek parametrelerini ekler; tablo kolonunu belirtirken eq. operatörü gerekir
  • Silme düğmesi, ilgili to-do’yu silmek için hx-post="/rpc/delete_todo" isteği gönderir
  • api.html_editable_task(_id int), belirli bir to-do’nun düzenlenmesini sağlayan input alanı HTML’ini döndürür
    • hx-post="/rpc/change_todo_task" ile değiştirilen görev adını gönderir
    • hx-trigger="submit,focusout" ile form gönderildiğinde veya odak dışına çıkıldığında günceller
    • hx-headers='{"Accept": "text/html"}' içerir
  • Veri değiştiren endpoint’lerin tamamı değişiklikten sonra tüm liste HTML’ini döndürür
    • api.change_todo_state(_id int, _done boolean): done kolonunu günceller
    • api.change_todo_task(_id int, _task text): task kolonunu günceller
    • api.delete_todo(_id int): _id değerine karşılık gelen to-do’yu siler
  • Şema önbelleği yenilendikten sonra http://localhost:3000/rpc/index adresinden to-do düzenleme, silme ve tamamlandı işaretleme işlemleri yapılabilir

1 yorum

 
GN⁺ 2023-12-19
Hacker News yorumları
  • PostgREST, en sevdiğim açık kaynak projelerden biri. Supabase’in 1 milyar dolarlık bir şirket hâline gelmesinde PostgREST ve Postgres’in mükemmel tasarımının büyük payı olduğunu düşünüyorum
    Supabase’in bu projeyi nasıl desteklediğini bilmiyorum ama bunun çok büyük ölçekte olmasını umuyorum. En az yüzlerce gelir üreten şirketin temel bağımlılık olarak kullandığı bir projenin yalnızca 12 ücretli destekçisi olduğunu görmek, açık kaynak finansmanının gerçekliğini üzücü kılıyor
    https://www.patreon.com/postgrest/about

    • Supabase yığınının temel bir parçası olduğu için, dediğin gibi PostgREST üzerinde ağırlıklı çalışması için baş maintainer Steve’i istihdam ediyoruz
      https://github.com/steve-chavez
    • Artık 13 kişi. Yine de hâlâ yalnızca aylık 1.529 $
    • PostgREST’in Supabase’in bir parçası olduğunu bilmiyordum. Supabase’in sıfırdan yapılmış bir taklit ürün olduğunu sanıyordum
    • Böyle durumlarda hep gelen klişe sözleri şimdiden duyar gibiyim: “Kullanıcıların seni maddi olarak destekleme yükümlülüğü yok”, “Hoşuna gitmiyorsa permissive lisansla yayımlamasaydın” gibi
      Bu yüzden artık yalnızca AGPLv3 veya benzeri lisanslar kullanıyorum. Ticari olarak kullanmak istiyorsan brüt cironun %1’ini öde gibi
  • Kavram kanıtı olarak hoş ve uygulaması da övgüye değer, ama önemsiz olmayan bir web uygulamasında bakımını yapmak kâbus gibi görünüyor

    • Kesinlikle daha çok web siteleri veya hafif uygulamalar için uygun. Yine de o kapsam içinde epey fazla şekilde kullanılabilir
    • Şu anda bakımı kolaylaştırmak için Sqitch kullanılıp kullanılamayacağını deniyorum. Hâlâ bir hack gibi hissettiriyor ve gerçek kullanım olasılığı konusunda şüphelerim var, ama eğlenceli ve birçok gelişmiş Postgres özelliği öğreniyorum
      https://sqitch.org/
    • Açıkçası bunu ana web uygulamamızda kullanırsak 100 kat kolaylaşmayacak kısmın ne olduğunu merak ediyorum
    • Bence şu an durum bu. Artık tek gereken, CI sürecinin bir parçası olarak HTMX route’larını veritabanı sunucusuna derleyip dağıtmanın bir yolu
  • Bu tür özelliklerin veya kodlama kalıplarının yeni ya da modern uygulamalarda da kullanılıp kullanılmadığını merak ediyorum
    CouchDB adlı JSON belge veritabanı HTTP tabanlı bir API sunuyordu ve JavaScript yorumlayıcısı içinde oluşturulabilecek herhangi bir formatta yanıt döndürebilen yerleşik liste/detay yöntemleri vardı. Yani istemci doğrudan veritabanını çağırıp HTML veya JSON alabiliyor, sunucuya gerek kalmıyordu
    Ama v1’den sonra bu yöndeki çalışmaları durdurdular, çünkü bakımı kâbusa dönüşüyordu. Eski PHP veya ASP dosyalarında SQL ifadeleriyle HTML’in iç içe olduğu güzel günleri hatırlayan çok kişi vardır; bu da pek farklı görünmüyor

    • Yeni nesil, geçmişte geçerli nedenlerle terk edilmiş şeyleri yeniden öğreniyor gibi
      Yaklaşık 13 yıl önce kişisel bir projede CouchDB’nin web ile ilgili özelliklerini gerçekten sevmiştim, ama ekip olarak çalışırken epey zahmetliydi
    • Modern demek zor. Oracle’da 25 yıldan uzun süre önce böyle şeyler vardı
  • Üzerinde çalıştığım tek PostgREST uygulaması berbattı. Çünkü bu tür “basit” framework’lerin çoğunda olduğu gibi, yalnızca gereksinimler karmaşıklaşana kadar basit kalıyorlar
    Asıl geliştiriciler istedikleri sonucu elde etmek için veritabanında bir sürü stored procedure kullanmak zorunda kaldılar, bu da ölçeklenebilirlik sorunlarına yol açtı. Her zamanki gibi çözüm SQL’e geri dönmek

    • Sanki o ekip işe uygun olmayan aracı seçmiş gibi geliyor. Endpoint’lerin çoğunda karmaşık backend mantığı varsa PostgREST kullanmamalısın
      PostgREST CRUD uygulamaları için tasarlandı ve karşılaştığım uygulamaların çoğu buna giriyor. Ara sıra gereken özel backend mantığı da ayrı bir sunucu veya edge function olarak çalıştırılıp ele alınabilir
    • PostGREST’i çok kullanıyorum ama güçlü guardrail’ler koyuyorum. Gerçek API katmanı her zaman olmalı; bence bu yalnızca temel yüklemeleri kolaylaştıran yardımcı bir araç olarak kullanılmalı
      Bu tür araçların hepsinde olduğu gibi, gerçek dünya gereksinimlerine gelince araca uyum sağlamanın maliyeti, yerine geçirmeye çalıştığı SQL + herhangi bir dil ve framework’ten daha kötü hâle geliyor. PostGREST zaten karmaşıklaşıyor; bu tür ek özellikler benim için cazibesini azaltıyor
    • Stored procedure’ler de sonuçta fonksiyon biçiminde SQL değil mi?
      Rails ortaya çıkıp herkesin iş mantığını yavaş sunucu tarafı dillerine koymanın iyi fikir olduğuna inanmasını sağlamadan önce, herkes uygulamaları böyle geliştiriyordu
  • Gerçekten temiz bir web geliştirme yığını. Yalnızca HTML ve veritabanı var; backend ve frontend’e gerek yok

    • 90’ların ortasında Ohio’daki Compuserve’i ziyaret etmiştim. Web’in yeni başladığı dönemdi ve orada tanıştığım bir mühendis, SQL stored procedure’lerinden HTML döndürerek yaptığı müzik mağazasını göstermişti :)
    • Bu sana havalı geliyorsa Omnigres’e de göz atmaya değer
      https://github.com/omnigres/omnigres
    • Bu yoldan zaten geçtik. Başta temiz görünüyor ama uzun vadeli bakım, destek ve eğitim için iyi değil
      HTMX’in parıltısı söndükten sonra o zamanki bakım sorumlusu, sonunda her şeyi baştan yazmak gerektiğini kabul edecek
    • Backend ve frontend hâlâ var. Sadece hepsi doğrudan veritabanı kodunun içine birbirine dolanmış durumda
    • Sonunda mainframe’e geri dönmüş olduk. Bu kez tarayıcı sadece terminal
  • Eski bir projede HTMX olmadan PostgREST kullanmıştım; ne kadar ileri götürülebileceği etkileyiciydi
    HTMX de iyi uyuyor gibi görünüyor, ama SQL fonksiyonları içinde HTMX şablonlarını ne kadar sürdürmek isterim pek emin değilim

    • Hiç ilgimi çekmiyor. Bunu PHP ile zaten yaşadık. Bu kalıpta statik analiz, yerel test, refactoring, atomik olarak teslim edilen büyük değişiklikler gibi önemli özellikler eksik
      Kurcalayıp bir şeyler yapmak için iyi, ama sağlam bir şey inşa etmek için uygun değil
  • Haskell açısından bakınca PostgREST ilginç. Fazla bariz bir proje gibi göründüğü için
    Ama tam da bu yüzden dâhice. Gerçekten Haskell’e özgü bir fikir olduğu için hoşuma gidiyor

  • Bu kavramı orta-büyük ölçekli uygulamalarda da iyi bir kullanıcı deneyimi sunan bakımı yapılabilir bir stack hâline getirmek için hangi ek araçların gerekli olduğunu düşünüyorsunuz?

    • Statik site sunumu için Astro(https://astro.build) kullanıyorum; basit, veri odaklı bileşenlerde ise PostgREST Htmx kullanıyorum
    • Orta-büyük ölçek söz konusuysa ayrı bir soyutlama katmanı, yani bir API gerektiğini düşünüyorum
      Ben de SQL’in üzerine benzer bir şey yapmaya çalışmıştım; teknoloji stack’i Jinja şablon SQL ve YML ile uygulanmış bir OpenAPI katmanıydı, ama yine de bunu iç araçlar kapsamıyla sınırlı tutacağımı düşünüyorum. Burada: https://jinj.at
  • İlgili Show HN: pg_render ile SQL’den HTML render etmek
    https://news.ycombinator.com/item?id=38677852

  • Unutmamak için bu uygulamaya bir görev yazmak istiyorum. Benim görevim şu:
    Bu durumda task sütunu hiçbir yerde temizleniyor gibi görünmüyor

    • Kötü eski günlerde, view veritabanıyla doğrudan konuştuğu için XSS çok yaygındı. Sonra araya template engine ve model koyunca sorun çözülmüş gibi görünmüştü
      Ama şimdi veritabanı view olduğuna göre XSS geri mi geldi? Bu önlenebilir bir sorun
    • Evet. htmx o script’i seve seve çalıştırır. Demoda da aynı bug vardı: https://github.com/bigskysoftware/htmx/pull/1995/files
    • Örnek dokümana yönelik bir korkuluk saldırısı gibi görünüyor. HTMX yalnızca HTML sunar; girdinin bir şekilde temizlenmesi gerekir
      HTML, bunu yapan herhangi bir template diliyle render edilebilir