PostgREST: htmx के साथ HTML कंटेंट उपलब्ध कराना
(postgrest.org)- अगर PostgreSQL फ़ंक्शन सीधे
text/htmlलौटाए, तो सिर्फ़ PostgREST और htmx के साथ ऐसा to-do ऐप बनाया जा सकता है जो AJAX अनुरोध के परिणाम लेकर DOM के हिस्सों को बदल दे - उदाहरण में authentication के बिना
web_anonकोapi.todosऔरapi.todos_id_seqकी permission दी जाती है, औरAccept: text/htmlअनुरोध संभालने के लिए custom media type जोड़ा जाता है - HTML assemble करने का काम SQL फ़ंक्शन करते हैं, और
api.sanitize_html,api.html_todo,api.html_all_todosinput escaping और list rendering संभालते हैं - स्क्रीन का व्यवहार
hx-post,hx-get,hx-target,hx-trigger,hx-vals,hx-headersसे बनता है, और response HTML#todo-list-areaया अलग-अलग edit area को replace करता है - यह सेटअप proof of concept के क़रीब है, और PostgREST पक्ष में HTML handling बेहतर करने के लिए
plmustacheपर काम चल रहा है
PostgREST और htmx की भूमिका
- PostgREST HTML content लौटाता है, और htmx AJAX अनुरोध के परिणाम में मिले HTML का उपयोग DOM के अंदर elements बदलने के लिए करता है
- htmx HTML response की अपेक्षा करता है, इसलिए यह उस flow के साथ अच्छी तरह मेल खाता है जहाँ server JSON की जगह HTML fragments लौटाता है
- यह उदाहरण दिखाता है कि दोनों तकनीकों को साथ इस्तेमाल करने पर कैसी संरचना संभव है; यह एक proof of concept है
- PostgREST HTML processing को और बेहतर बनाने के लिए plmustache पर काम कर रहा है
to-do ऐप की तैयारी
- यह उदाहरण Tutorial 0 - Get it Running पर आधारित एक to-do ऐप है
- सरलता के लिए authentication का उपयोग नहीं किया गया है, और
web_anonuser को ज़रूरी permissions दी जाती हैंapi.todostable परgrant allapi.todos_id_seqsequence परgrant usage, select
- browser के
Accept: text/htmlअनुरोध को PostgREST द्वारा HTML के रूप में पहचानने के लिए media type handler जोड़ना होगा"text/html"domain कोtextके रूप में बनाया जाता है- इस सेटिंग से PostgREST raw HTML document लौटा सकता है
बेसिक HTML पेज लौटाना
api.index()फ़ंक्शन"text/html"लौटाता है और एक बेसिक HTML document बनाता है- पेज में
PostgREST + HTMX To-Do Listशीर्षक के साथ ये resources शामिल हैं - browser में यह पेज
http://localhost:3000/rpc/indexपर खोला जा सकता है
सूची render करना और to-do जोड़ना
- मौजूदा to-do सूची को HTML में बनाने के लिए तीन SQL फ़ंक्शन उपयोग किए जाते हैं
api.sanitize_html(text):&,",>,<,'अक्षरों को HTML entities में बदलता हैapi.html_todo(api.todos): एक single to-do item को HTML fragment के रूप में format करता हैapi.html_all_todos(): सभी items को एक HTML string में जोड़ता है, और item न होने परThere is nothing else to do.संदेश लौटाता है
api.html_todoऔरapi.html_all_todosसूची templates बनाने के लिए internal फ़ंक्शन हैं; इन्हें सीधे PostgREST endpoint के रूप में उपयोग नहीं किया जाताapi.add_todo(_task text)नया to-doapi.todosमें insert करने के बाद updated पूरी सूची का HTML लौटाता है- updated
api.index()में htmx और input form शामिल हैhx-headers='{"Accept": "text/html"}'को parent element पर रखा जाता है ताकि child htmx requests HTML response माँगें- यह header न हो तो PostgREST अनुरोध को HTML के रूप में पहचान नहीं पाएगा
- to-do जोड़ने वाला form htmx attributes से काम करता है
hx-post="/rpc/add_todo":_taskinput value को/rpc/add_todoपर POST करता हैhx-target="#todo-list-area": response HTML को to-do list area में डालता हैhx-trigger="submit": form submit होने पर request भेजता हैhx-on="htmx:afterRequest: this.reset()": request पूरी होने के बाद form खाली करता है
- नए functions और बदलाव लागू करने के लिए schema cache refresh करना होगा
- इसके बाद
http://localhost:3000/rpc/indexपर सूची दिखना और नया to-do जोड़ना देखा जा सकता है
संपादन, हटाना, पूरा होने की स्थिति बदलना
api.html_todoको बढ़ाकर हर item में completion status बदलने, edit करने और delete करने का UI शामिल किया जाता है- completion status बदलना
<form>और htmx attributes से संभाला जाता हैhx-post="/rpc/change_todo_state": संबंधित endpoint पर AJAX POST request भेजता हैhx-vals='{"_id": ..., "_done": ...}': hidden input की जगह request parameters जोड़ता हैhx-trigger="click": item पर click होने पर request चलाता है
- edit button किसी खास task को input field में बदल देता है
hx-get="/rpc/html_editable_task": editable HTML input लौटाने वाले endpoint को कॉल करता हैhx-target="#todo-edit-area-...": पूरी सूची की जगह सिर्फ़ उस task area को replace करता हैhx-valsGET request parameters जोड़ता है, और table column को दर्शाते समयeq.operator की ज़रूरत होती है
- delete button
hx-post="/rpc/delete_todo"से उस to-do को हटाने का request भेजता है api.html_editable_task(_id int)किसी विशेष to-do को edit करने के लिए input field का HTML लौटाता हैhx-post="/rpc/change_todo_task"से बदला हुआ task name submit किया जाता हैhx-trigger="submit,focusout"submit या focus out होने पर update करता हैhx-headers='{"Accept": "text/html"}'शामिल होता है
- सभी data-changing endpoints बदलाव के बाद पूरी सूची का HTML लौटाते हैं
api.change_todo_state(_id int, _done boolean):donecolumn को update करता हैapi.change_todo_task(_id int, _task text):taskcolumn को update करता हैapi.delete_todo(_id int):_idके अनुरूप to-do को delete करता है
- schema cache refresh करने के बाद
http://localhost:3000/rpc/indexपर to-do edit, delete और completion handling संभव है
1 टिप्पणियां
Hacker News की रायें
PostgREST मेरे पसंदीदा open source projects में से एक है। मुझे लगता है कि Supabase के 1 billion dollar की कंपनी बनने में PostgREST और Postgres के बेहतरीन design का बड़ा योगदान है
मुझे नहीं पता Supabase इस project को कैसे sponsor करता है, लेकिन उम्मीद है कि यह बहुत बड़े स्तर पर होगा। यह project कम से कम सैकड़ों revenue-generating companies के लिए core dependency है, फिर भी सिर्फ 12 paid sponsors हैं—open source funding की वास्तविकता देखकर दुख होता है
https://www.patreon.com/postgrest/about
https://github.com/steve-chavez
इसलिए अब मैं सिर्फ AGPLv3 या उससे मिलते-जुलते licenses इस्तेमाल करता हूँ। अगर commercial use करना है, तो gross revenue का 1% दो—ऐसा मॉडल
Proof of concept के तौर पर यह बढ़िया है और implementation भी तारीफ़ के काबिल है, लेकिन किसी non-trivial webapp में maintain करना nightmare जैसा लगता है
https://sqitch.org/
जिज्ञासा है कि ऐसी features या coding patterns नई या modern applications में भी इस्तेमाल होती हैं या नहीं
CouchDB नाम का JSON document database HTTP-based API देता था, और इसमें built-in list/detail methods थे जो JavaScript interpreter के अंदर बनाए जा सकने वाले किसी भी format में response दे सकते थे। यानी client सीधे database को call करके HTML या JSON पा सकता था और server की जरूरत नहीं थी
लेकिन v1 के बाद उन्होंने उस दिशा में काम बंद कर दिया, क्योंकि maintenance nightmare बन जाती थी। बहुत से लोगों को पुराने PHP या ASP files के अच्छे दिन याद होंगे, जहाँ एक ही file में SQL statements और HTML मिले होते थे; यह उससे बहुत अलग नहीं लगता
करीब 13 साल पहले एक personal project में मुझे CouchDB की web-related features बहुत पसंद थीं, लेकिन team के लिए उन्हें संभालना काफी inconvenient था
जिस एकमात्र PostgREST app पर मैंने काम किया, वह भयानक था। क्योंकि ऐसे ज्यादातर “simple” frameworks की तरह, वे सिर्फ तब तक simple रहते हैं जब तक requirements complex नहीं हो जातीं
मूल authors desired result पाने के लिए database में ढेर सारे stored procedures इस्तेमाल करने लगे, और इससे scalability issues पैदा हुए। हमेशा की तरह solution SQL पर वापस लौटना ही है
PostgREST CRUD apps के लिए बनाया गया है, और जिन applications से मेरा सामना होता है उनमें से बहुत-सी इसी category में आती हैं। कभी-कभार जरूरी custom backend logic को अलग server या edge functions के रूप में चलाकर handle किया जा सकता है
ऐसे सभी tools की तरह, real-world requirements आने पर tool के हिसाब से adapt करने की cost, उस चीज से भी खराब हो जाती है जिसे यह replace करना चाहता था—SQL + कोई language और framework। PostGREST भी पहले से complex होता जा रहा है, और ऐसी extra features मेरे लिए इसकी appeal घटाती हैं
Rails के आने और सबको यह यकीन दिलाने से पहले कि slow server-side language में business logic डालना अच्छा idea है, लोग इसी तरह apps बनाते थे
सचमुच साफ-सुथरा web development stack है। बस HTML और database हैं, backend और frontend की जरूरत नहीं
https://github.com/omnigres/omnigres
HTMX की चमक फीकी पड़ने के बाद उस समय का maintainer आखिर मान लेगा कि सब कुछ scratch से फिर लिखना पड़ेगा
एक पुराने project में मैंने HTMX के बिना PostgREST इस्तेमाल किया था, और यह देखकर impressed था कि इसे कितनी दूर तक push किया जा सकता है
HTMX भी fit बैठता दिखता है, लेकिन SQL functions के अंदर HTMX templates को कितना maintain करना चाहूँगा, यह पक्का नहीं है
खेलने-कूदने के लिए अच्छा है, लेकिन stable चीज बनाने के लिए suitable नहीं
Haskell के नजरिए से PostgREST interesting है। क्योंकि यह बहुत obvious project जैसा दिखता है
लेकिन ठीक इसी वजह से यह genius है। सच में Haskell जैसी idea है, इसलिए अच्छा लगता है
इस concept को medium-to-large applications में भी अच्छे user experience वाला maintainable stack बनाने के लिए आपको कौन-से अतिरिक्त tools ज़रूरी लगते हैं?
मैंने भी SQL के ऊपर कुछ ऐसा ही बनाने की कोशिश की थी, और tech stack Jinja template SQL और YML से implement की गई OpenAPI layer था, फिर भी शायद इसे internal tools के दायरे तक ही सीमित रखूँगा। यह यहाँ है: https://jinj.at
संबंधित Show HN: pg_render से SQL में HTML render करना
https://news.ycombinator.com/item?id=38677852
मैं इस app में न भूलने के लिए एक task लिखना चाहता हूँ। मेरा task यह है:
इस मामले में task column कहीं भी sanitize होता नहीं दिखता
लेकिन अब database ही view है, तो क्या XSS फिर से आ गया? यह रोकी जा सकने वाली समस्या है
HTML को ऐसी किसी भी template language से render किया जा सकता है जो यह handling कर देती हो