Pennybase - โอเพนซอร์ส BaaS แบบเบาพิเศษที่ทำงานบนไฟล์
(github.com/zserge)- BaaS (Backend-as-a-Service) ขนาดจิ๋วพิเศษ ที่พัฒนาด้วยโค้ดไม่ถึง 1,000 บรรทัดโดยใช้เพียงไลบรารีมาตรฐานของ Go
- ให้ความสามารถแบ็กเอนด์หลักที่คล้ายกับ Firebase/Supabase/Pocketbase โดยอิงกับ ไฟล์ในเครื่อง
- การจัดเก็บข้อมูลแบบอิงไฟล์ โดยใช้เรคคอร์ดที่มีการเวอร์ชันใน CSV
- REST API ที่ส่งคืน JSON
- การยืนยันตัวตน ด้วย session cookie และ Basic Auth
- รองรับ RBAC และ ระบบสิทธิ์ แบบอิงเจ้าของ
- การตรวจสอบสคีมา
- การเรนเดอร์เทมเพลต บนพื้นฐานของ Go template
วิธีการทำงาน
-
การจัดเก็บข้อมูล
- เก็บข้อมูลทั้งหมดไว้ใน ไฟล์ CSV ที่มนุษย์อ่านได้ โดยหนึ่งแถวต่อหนึ่งเรคคอร์ด
- คอลัมน์แรกคงที่เป็น ID ของเรคคอร์ด และ คอลัมน์ที่สองคงที่เป็นหมายเลขเวอร์ชัน
- วิธีจัดเก็บเป็นแบบ append-only โดยจะไม่เขียนทับเรคคอร์ดเดิม แต่จะเพิ่มแถวเวอร์ชันใหม่ทุกครั้งที่มีการอัปเดต
- ระหว่างการอ่าน จะใช้งานเฉพาะเรคคอร์ดเวอร์ชันล่าสุดเสมอ
- เพื่อให้ค้นหาและอัปเดตได้รวดเร็ว จะเก็บ memory index ของข้อมูล file offset ของเรคคอร์ดเวอร์ชันล่าสุดแยกตามแต่ละรีซอร์ส
s1,1,_permissions,_id,text,,,^.+$ s2,1,_permissions,_v,number,1,, s3,1,_permissions,resource,text,,,^.+$ s4,1,_permissions,action,text,,,^.+$ s5,1,_permissions,field,text,,,^.*$ s6,1,_permissions,role,text,,,^.*$ s7,1,_users,_id,text,,,^.+$ s8,1,_users,_v,number,1,, s9,1,_users,salt,text,,, s10,1,_users,password,text,,,^.+$ s11,1,_users,roles,list,,, s12,1,todo,_id,text,,,^.+$ s13,1,todo,_v,number,1,, s14,1,todo,description,text,0,0,".+" s15,1,todo,completed,number,0,1,""
-
การจัดการผู้ใช้และสิทธิ์
- ข้อมูลยืนยันตัวตนของผู้ใช้และรายการบทบาท (Role) จะถูกเก็บไว้ในไฟล์
_users.csvadmin,1,salt,5V5R4S...====,"admin" alice,1,salt,PXHQWN...====, - ใช้โครงสร้าง CSV เดียวกับทุกรีซอร์สอื่น แต่ชื่อคอลเลกชันคือ
_users - ไม่สามารถสร้างผู้ใช้ผ่าน API ได้ และต้องแก้ไขไฟล์โดยตรงเท่านั้น
- ข้อมูลยืนยันตัวตนของผู้ใช้และรายการบทบาท (Role) จะถูกเก็บไว้ในไฟล์
-
การจัดการสิทธิ์
- กำหนดกฎควบคุมการเข้าถึงแยกตามรีซอร์สใน
_permissions.csvp1,1,todo,read,,*,"ผู้ใช้ที่ยืนยันตัวตนแล้วทุกคนสามารถอ่าน ToDo ได้" p2,1,todo,create,,*,"ผู้ใช้ที่ยืนยันตัวตนแล้วทุกคนสามารถเพิ่ม ToDo ใหม่ได้" p3,1,todo,update,owner,"admin,editor","admin/editor สามารถอัปเดต ToDo ได้" p4,1,todo,delete,owner,"admin,editor","admin/editor สามารถลบ ToDo ได้" - แต่ละแถวหมายถึงกฎสิทธิ์หนึ่งข้อ
- กำหนดกฎควบคุมการเข้าถึงแยกตามรีซอร์สใน
REST API
- ให้บริการ REST API โดยอัตโนมัติตามรีซอร์ส (คอลเลกชัน) ที่กำหนดไว้ใน
_schemas.csv GET /api/{resource}?sort_by={field}: ดูเรคคอร์ดทั้งหมดของรีซอร์สนั้น พร้อมจัดเรียงได้GET /api/{resource}/{id}: ดูเรคคอร์ดเดี่ยวที่มี ID ที่กำหนดPOST /api/{resource}: สร้างเรคคอร์ดใหม่ ต้องมีสิทธิ์ "create"PUT /api/{resource}/{id}: แก้ไขเรคคอร์ดเดิม ต้องมีสิทธิ์ "update"DELETE /api/{resource}/{id}: ลบเรคคอร์ดที่ระบุ ต้องมีสิทธิ์ "delete"GET /api/events/{resource}: สมัครรับสตรีมแบบเรียลไทม์ของ server-side events (SSE) สำหรับรีซอร์สนั้น ต้องมีสิทธิ์ "read"-
วิธีการยืนยันตัวตน
- รองรับการยืนยันตัวตนของคำขอ API ด้วย Basic Auth หรือ session cookie
- การสร้าง session cookie:
- ส่งคำขอไปที่
POST /api/loginพร้อมusernameและpasswordใน body - การตอบกลับจะมี session cookie รวมอยู่ด้วย ทำให้คำขอถัดไปได้รับการยืนยันตัวตนโดยอัตโนมัติ
- ส่งคำขอไปที่
- ออกจากระบบ:
- เมื่อเรียก
/api/logoutจะทำให้ session ใช้งานไม่ได้และลบ cookie
- เมื่อเรียก
ไฟล์สแตติกและเทมเพลต
- สามารถเสิร์ฟ ไฟล์สแตติก เช่น HTML, CSS, JavaScript ที่อยู่ในไดเรกทอรี
staticได้โดยตรง- ตัวอย่าง: เข้าถึงไฟล์
static/index.htmlได้ผ่านhttp://ที่อยู่เซิร์ฟเวอร์/index.ht…
- ตัวอย่าง: เข้าถึงไฟล์
- นอกจากนี้ยังรองรับ การเรนเดอร์ HTML template โดยใช้แพ็กเกจ
html/templateของ Go- ไฟล์เทมเพลตจะอยู่ในไดเรกทอรี
templatesและจะเรนเดอร์ให้อัตโนมัติเมื่อเข้าถึงผ่าน URL
- ไฟล์เทมเพลตจะอยู่ในไดเรกทอรี
- ข้อมูลและฟังก์ชันที่ใช้ได้ภายในเทมเพลต
.User: ข้อมูลผู้ใช้ที่ยืนยันตัวตนอยู่ในปัจจุบัน (ถ้ายังไม่ยืนยันตัวตนจะเป็นnil).Store: อินสแตนซ์ store ของ Pennybase (ใช้สำหรับค้นหาและแสดงรายการรีซอร์ส).Request: อ็อบเจ็กต์ HTTP request ปัจจุบัน.ID: ID ของรีซอร์สที่กำลังเข้าถึง (ถ้ามี).Authorize: ฟังก์ชันสำหรับตรวจสอบสิทธิ์การกระทำต่อรีซอร์สที่กำหนด
ความสามารถของ Hook
- สามารถขยายการทำงานได้ด้วยฟังก์ชัน hook เดียว
- ฟังก์ชัน hook จะถูกเรียกโดยอัตโนมัติเมื่อมีการสร้าง (create), แก้ไข (update), หรือลบ (delete) ในทุกรีซอร์ส
-
หลักการทำงาน
- ฟังก์ชัน hook จะทำงานโดยรับอาร์กิวเมนต์ 4 ตัวดังนี้:
trigger: ประเภทของแอ็กชัน (เช่น create, update, delete)resource: ชื่อรีซอร์สที่เป็นเป้าหมายของงานuser: ข้อมูลผู้ใช้ที่ทำคำขอres: ข้อมูลรีซอร์สที่กำลังเปลี่ยนแปลง
- สามารถทำ การตรวจสอบเพิ่มเติมหรือแก้ไขข้อมูล ได้ที่จุด hook
- เช่น เมื่อสร้างรีซอร์สข้อความ ก็สามารถกรอก author และเวลาสร้างให้อัตโนมัติได้
- หากฟังก์ชัน hook คืนค่า error แอ็กชันนั้นจะหยุดทันที และส่งการตอบกลับข้อผิดพลาดไปยังไคลเอนต์
- จึงสามารถใช้เพื่อเพิ่มการตรวจสอบสิทธิ์ แก้ไขข้อมูลอัตโนมัติ ทริกเกอร์อีเวนต์ภายนอก และลอจิกแบบคัสตอมอื่น ๆ ได้หลากหลาย
- ฟังก์ชัน hook จะทำงานโดยรับอาร์กิวเมนต์ 4 ตัวดังนี้:
ข้อจำกัดและข้อควรระวัง
- การจัดการผู้ใช้/สิทธิ์/สคีมาทั้งหมด ต้องแก้ไขไฟล์ CSV โดยตรง
- ไม่เหมาะกับข้อมูลขนาดใหญ่ การแยกสิทธิ์ที่ซับซ้อน หรือสภาพแวดล้อมแบบกระจายที่ต้องการประสิทธิภาพสูง
- ทำงานด้วยโค้ด Go มาตรฐานเท่านั้นโดยไม่มีไลบรารีภายนอก (มุ่งเน้นเพื่อการเรียนรู้/งานแบบง่าย)
- ใช้ไลเซนส์ MIT และสามารถนำซอร์สโค้ดกับโครงสร้างไปใช้งานได้อย่างอิสระ
- ยินดีรับการมีส่วนร่วม แต่ขอให้รักษา ความเรียบง่าย/ความชัดเจนของโค้ด โดยมีแผนจะดูแลโดยเน้นการแก้บั๊กมากกว่าการเพิ่มฟีเจอร์เพิ่มเติม
1 ความคิดเห็น
ว้าว...