PocketBase: โอเพนซอร์สแบ็กเอนด์แบบไฟล์เดียว
(pocketbase.io)- PocketBase รวมฐานข้อมูลแบบเรียลไทม์ ระบบยืนยันตัวตน ที่เก็บไฟล์ และแดชบอร์ดผู้ดูแลไว้ในไฟล์เดียว ทำให้สร้างแบ็กเอนด์ขนาดเล็กได้อย่างรวดเร็ว
- ฐานข้อมูลในตัวมาพร้อม ตัวสร้างสคีมา, การตรวจสอบข้อมูล, การสมัครรับข้อมูลแบบเรียลไทม์ และ REST API ช่วยลดภาระในการตั้งค่าแบ็กเอนด์แยกต่างหาก
- การจัดการผู้ใช้รองรับการสมัครด้วยอีเมล/รหัสผ่านและ การสมัครผ่าน OAuth2 โดยใช้ Google, Facebook, GitHub และ GitLab ได้
- ไฟล์สามารถเก็บไว้ในเครื่องหรือใน S3 storage และแนบสื่อเข้ากับเรคอร์ดฐานข้อมูลหรือสร้างภาพย่อได้ทันที
- เริ่มต้นใช้งานเป็นแอปเดี่ยวได้ จากนั้นขยายต่อด้วย hook ของ Go และ JavaScript จึงสร้าง แบ็กเอนด์แบบพกพาที่ปรับแต่งเอง ได้ง่าย
ความสามารถของแบ็กเอนด์ในไฟล์เดียว
- PocketBase เป็นโอเพนซอร์สแบ็กเอนด์ที่ให้ฐานข้อมูลแบบเรียลไทม์ ระบบยืนยันตัวตน ที่เก็บไฟล์ และแดชบอร์ดผู้ดูแลในไฟล์เดียว
-
ฐานข้อมูลในตัว
- ฐานข้อมูลในตัวที่เน้นประสิทธิภาพมี ตัวสร้างสคีมา มาให้
- มีการตรวจสอบข้อมูล การสมัครรับข้อมูลแบบเรียลไทม์ และ REST API ที่ใช้งานง่าย
การยืนยันตัวตนและการสมัครผู้ใช้
- สามารถจัดการผู้ใช้ของแอปและรองรับการสมัครแบบอีเมล/รหัสผ่านได้
- ยังรองรับ การสมัครผ่าน OAuth2 ซึ่งรวมถึง Google, Facebook, GitHub และ GitLab
การจัดเก็บไฟล์และการจัดการสื่อ
- ไฟล์สามารถเก็บไว้ในเครื่องหรือใน S3 storage ได้
- สามารถแนบสื่อกับเรคอร์ดฐานข้อมูลและสร้างภาพย่อได้ทันที
วิธีใช้งานและการขยายต่อ
- PocketBase ใช้งานเป็น แอปเดี่ยว ได้
- หากใช้ในลักษณะเฟรมเวิร์ก ก็สามารถขยายต่อด้วย hook ของ Go และ JavaScript ได้
- วิธีนี้ช่วยให้สร้างแบ็กเอนด์แบบพกพาที่ปรับแต่งเองได้
ตัวอย่าง JavaScript SDK
- JavaScript SDK นำเข้า
PocketBaseและสร้างไคลเอนต์ด้วยที่อยู่เช่นhttp://127.0.0.1:8090 - ใช้
pb.collection('example').getList()เพื่อดูรายการเรคอร์ดของคอลเลกชันและค้นหาได้- ตัวอย่างใช้ตัวกรอง
title != "" && created > "2022-08-01"และการจัดเรียง-created,title
- ตัวอย่างใช้ตัวกรอง
- ใช้
getOne('RECORD_ID'),delete('RECORD_ID'),create()เพื่อดึง ลบ และสร้างเรคอร์ดเดี่ยว - ใช้
subscribe('*', ...)เพื่อสมัครรับการเปลี่ยนแปลงของเรคอร์ดในคอลเลกชัน และใช้unsubscribe()เพื่อยกเลิกการสมัครรับ
1 ความคิดเห็น
ความเห็นจาก Hacker News
เคยใช้ PocketBase เป็นแบ็กเอนด์/ฐานข้อมูลของแอป และมันยอดเยี่ยมมาก โดยฝั่งฟรอนต์เอนด์ใช้ React กับ Vite
ใช้หลัก ๆ สำหรับการยืนยันตัวตนและติดตามบัญชีแบบเสียเงิน/ฟรี โฮสต์ได้ง่ายมาก และยุ่งยากน้อยกว่าการโฮสต์ Appwrite หรือ Supabase เองมาก โดยเฉพาะ Supabase ที่ค่อนข้างจุกจิก ส่วน Appwrite แม้จะเปิดขึ้นมาบน CapRover ได้เร็ว แต่ก็เกินความจำเป็นสำหรับสิ่งที่ต้องใช้
ฟีเจอร์ view collection ช่วยให้ส่งกลับเฉพาะข้อมูลบางส่วนที่ต้องการได้ง่าย และตอนนี้ก็กำลังใช้แบบ join ระหว่างคอลเลกชันผู้ใช้กับคอลเลกชันผู้ใช้แบบเสียเงิน เพื่อคืนค่าเฉพาะช่วงเวลาที่เป็นสมาชิกแบบเสียเงิน: https://pocketbase.io/docs/collections/#view-collection
ยังสามารถขยายด้วย Go หรือ JS ได้ ดังนั้นถ้าความต้องการไม่ได้ซับซ้อนมาก ก็อาจไม่ต้องมีแบ็กเอนด์แยกเลย: https://pocketbase.io/docs/use-as-framework/
กำลังพัฒนาด้วย PocketBase มาได้ 2 เดือนแล้ว และมีแผนจะขึ้นระบบจริงภายใน 1-2 เดือน
ผมกำลังทำเว็บแอปให้บริษัทของเพื่อน และต้องการระบบที่เรียบง่ายซึ่งส่งต่องานได้ง่าย ทั้งระบบรันอยู่บน ไบนารีไฟล์เดียว ของ PocketBase ตัวเดียว มีทั้งเว็บเซิร์ฟเวอร์, JavaScript ฝั่งเซิร์ฟเวอร์ (TypeScript ที่คอมไพล์แล้ว) และฐานข้อมูล SQLite อยู่ในโปรเซสเดียว โฮสต์อยู่บน Vultr เดือนละ 12 ดอลลาร์ ส่วนฟรอนต์เอนด์เขียนด้วย SvelteKit static adapter + Svelte + TypeScript
PocketBase ทำมาได้ดี และผู้สร้างก็ตอบคำถามได้เร็วและชัดเจนมาก แต่เอกสารยังมีช่องว่างอยู่บ้าง, ตัวโหลด CSV ต้องเขียนเอง และถ้าใช้วัตถุจำนวนมากผ่านอินเทอร์เฟซ CRUD ก็จะช้าอยู่บ้าง แม้จะเขียนให้เร็วขึ้นผ่านโค้ดฝั่งเซิร์ฟเวอร์ได้ก็ตาม การทดสอบหน่วยของ JavaScript ฝั่งเซิร์ฟเวอร์ก็ต้องยัดใส่เข้าไปแบบฝืน ๆ และก็ยังเสียดายที่ Copilot/ChatGPT ยังช่วยตอบคำถามเรื่องนี้ได้ไม่ดีพอ
ไม่มีวิธีตั้งค่าเพจ 404 ของเว็บเซิร์ฟเวอร์ และยังมีข้อแปลกตรงที่ตำแหน่งไฟล์ในไฟล์ซิสเต็มของไบนารีมีความสำคัญ ดูเป็นการออกแบบตามการใช้งานของผู้สร้างเอง จึงต้องยอมรับตัวเลือกแบบนั้น
ถึงอย่างนั้นมันก็ตรงกับความต้องการพอดี เรียบง่าย และเขียนโค้ดทั้งหมดด้วยภาษาเดียวคือ TypeScript ได้ แม้ไม่ใช่ระบบที่แรงมาก แต่ก็ไม่จำเป็นสำหรับงานนี้ พองานนี้เสร็จแล้วก็ตั้งใจจะทำไซด์โปรเจ็กต์อีกตัวด้วย PocketBase เพราะมันง่ายขนาดนั้น และในสัญญากับบริษัทเพื่อนก็ยังตกลงกันว่าจะบริจาคให้ PocketBase ด้วย
ใช้ PocketBase ในระบบจริงมาหลายเดือนแล้ว โดยฟรอนต์เอนด์ใช้ alpinejs
ปรัชญาการพัฒนาตรงใจมาก มันเป็นซอฟต์แวร์ที่ใช้งานจริงได้ดี น่าใช้ และมีประโยชน์ พร้อมทั้งพัฒนาขึ้นทุกสัปดาห์โดยไม่บวมด้วยฟีเจอร์เกินจำเป็น
แต่ก็เริ่มเห็นว่ายิ่งเป็นที่นิยมมากขึ้น การถกเถียงและ issue ต่าง ๆ ก็ยิ่งชวนเหนื่อย กลัวว่าผู้สร้างจะต้องแบกรับการซัพพอร์ตในระดับที่ให้มาโดยตลอดจนหมดไฟ
ถ้าใครหารายได้จากสิ่งนี้อยู่ ขอแนะนำอย่างยิ่งให้ช่วยสนับสนุนโปรเจ็กต์ผ่าน Open Collective
ติดตาม PocketBase มาตั้งแต่ช่วงแรก ๆ และสิ่งที่ดีที่สุดของโปรเจ็กต์นี้คือมัน หลีกเลี่ยงความซับซ้อนอย่างตั้งใจ และโฟกัสกับแนวทางที่เรียบง่ายและมินิมอล
ความง่ายในการ deploy แค่เอาไบนารีไฟล์เดียวขึ้นเซิร์ฟเวอร์ก็เสร็จแล้วก็น่าสนใจมาก หลังจากมีการรองรับ JavaScript ในแบ็กเอนด์ ก็รู้สึกว่ามันกลายเป็นตัวเลือกที่จริงจังพอจะท้าชนเฟรมเวิร์กอย่าง Remix หรือ Next.js ได้ รอ v1 อยู่
จริง ๆ จะดึงข้อมูลทั้งหมดมาแล้วจัดการใน Node ก็ได้ แต่การแก้ใน PocketBase โดยตรงก็ง่ายพออยู่แล้ว ไม่ได้คิดว่ามันแทน Next หรือ Remix ได้ แต่ขอแนะนำอย่างมากให้เพิ่มเข้าไปในสแตกเพื่อทำให้ระบบง่ายขึ้น
ผมกำลังมองหาฟรอนต์เอนด์ที่วางทับบนฐานข้อมูล SQLite ได้โดยตรง ลบ Vivino ไปแล้วเพราะมันมี พาร์ตเนอร์มากกว่า 800 ราย ที่แชร์ข้อมูลของผม
จุดประสงค์คือจะออกแบบและเก็บคอลเลกชันไวน์ของตัวเอง ดังนั้นชุดที่มีทั้งไฟล์รันได้ไฟล์เดียว, แอดมินอินเทอร์เฟซ และฐานข้อมูล ซึ่งเก็บไว้ในโน้ตบุ๊กและรวมอยู่ในแบ็กอัปได้ ก็ดูเหมือนตรงกับสิ่งที่ต้องการพอดี นี่แหละเหตุผลที่ทำให้กลับมาอ่าน HN อยู่เสมอ
ดีใจที่เห็นว่ามีโอเพนซอร์สโปรเจ็กต์ดี ๆ ในพื้นที่นี้เพิ่มขึ้น Grist และ NocoDB ก็น่าพูดถึงด้วย โดยทั้งคู่โฟกัสด้านการจัดการฐานข้อมูลมากกว่า
น่าประทับใจที่ทั้งคู่ก็เริ่มต้นใช้งานได้ง่ายมากเช่นกัน ไม่ว่าจะเป็นแบบไฟล์เดียวหรือมาในรูปแบบ Electron
https://github.com/gristlabs
https://nocodb.com/
ลองไล่อ่านเอกสารแล้ว แต่ยังไม่ชัดว่ามันจัดการบางเรื่องอย่างไร
เช่น การควบคุมสิทธิ์ระดับแถวเพื่อให้ผู้ใช้เข้าถึงได้เฉพาะข้อมูลของตัวเอง, การเชื่อมต่อภายนอกอย่างการส่งอีเมลหรือทริกเกอร์, การ export/import CSV และ internationalization อยากรู้ว่าสิ่งเหล่านี้ทำได้ครบและตรงไปตรงมาหรือไม่ หรือว่าทั้งหมดต้องขยายด้วย Go หรือ JS เอง เครื่องมือดูดีมากนะ
อย่างที่อีกคนบอกไว้ คุณควบคุมการเข้าถึงระดับแถวได้ด้วย API rules ส่วนการส่งอีเมล, ตั้งตัวจับเวลา, หรือส่งคำขอไปยังเว็บเซิร์ฟเวอร์อื่นก็ทำได้ แม้ผมยังไม่ได้ใช้เอง แต่มีเอกสารอยู่: https://pocketbase.io/docs/js-sending-emails/
การ import CSV ต้องเขียนเอง และกำลังคิดว่าจะปล่อยเป็นโอเพนซอร์ส ส่วน internationalization จะทำอย่างไรนั้นขึ้นอยู่กับว่าคุณต้องการฟีเจอร์แบบไหน แต่โดยรวมดูจะเป็นเรื่องฝั่งฟรอนต์เอนด์มากกว่า
API Rules: https://pocketbase.io/docs/api-rules-and-filters/#api-rules
Hooks: https://pocketbase.io/docs/js-overview/
ในแผงผู้ดูแลระบบมีการสำรองข้อมูล และมีการนำเข้า/ส่งออกสคีมาของคอลเลกชัน
ส่วนที่เหลือ นอกจากอีเมลยืนยันตัวตนแล้ว ส่วนใหญ่ต้องอาศัยการขยาย แต่รูปแบบที่ง่ายที่สุดของการขยายก็คือการเพิ่มฟังก์ชัน JavaScript ธรรมดาเข้าไปใน event วงจรชีวิตของเรคคอร์ด โดยปกติจะรันก่อนหรือหลังการ insert/update/delete และมี Go API หลายตัวที่เปิดให้กับรันไทม์ JavaScript สำหรับทำงานกับไฟล์ซิสเต็ม, การเข้ารหัส, HTTP และอีเมล
เรื่อง internationalization ก็จัดการได้ด้วยเทมเพลตและฐานข้อมูล
ในบรรดา PaaS ทั้งหมดที่เคยใช้ รวมถึง Supabase และ Appwrite ด้วยนั้น PocketBase ดีที่สุดแล้ว ทั้งเร็ว ฟีเจอร์เข้าใจง่าย โฮสต์เองได้จริง และการ deploy ก็สนุก
ใช้ PocketBase กับระบบจริงของแอปมือถือมาหลายเดือนแล้ว และจนถึงตอนนี้ก็ราบรื่นมาก
เมื่อใช้ร่วมกับ JS SDK มันกลายเป็นเฟรมเวิร์กแบ็กเอนด์เริ่มต้นที่ผมเลือกสำหรับแทบทุกกรณีที่ไม่ต้องใช้ไลบรารีเฉพาะทางอย่างแมชชีนเลิร์นนิง
PocketBase ดีมากจนผมลองทำ Nuxt 3 starter เล็ก ๆ ขึ้นมา: https://github.com/fayazara/pocketbase-nuxt
ในตัวอย่างมีทั้งการยืนยันตัวตน, route rules, การทำงานแบบ CRUD, real-time events และ storage ยังต้องรีแฟกเตอร์อีกหน่อย แต่ระหว่างทำสนุกมาก และอยากลองเพิ่ม Stripe subscription เข้าไปเพื่อดันขีดจำกัดของ route rules ดู ยังไม่รู้ว่าจะทำอย่างไร แต่จะลองหาทางต่อไป