21 คะแนน โดย xguru 2025-07-14 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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.csv
      admin,1,salt,5V5R4S...====,"admin"  
      alice,1,salt,PXHQWN...====,  
      
    • ใช้โครงสร้าง CSV เดียวกับทุกรีซอร์สอื่น แต่ชื่อคอลเลกชันคือ _users
    • ไม่สามารถสร้างผู้ใช้ผ่าน API ได้ และต้องแก้ไขไฟล์โดยตรงเท่านั้น
  • การจัดการสิทธิ์

    • กำหนดกฎควบคุมการเข้าถึงแยกตามรีซอร์สใน _permissions.csv
      p1,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 ได้โดยตรง
  • นอกจากนี้ยังรองรับ การเรนเดอร์ 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 แอ็กชันนั้นจะหยุดทันที และส่งการตอบกลับข้อผิดพลาดไปยังไคลเอนต์
      • จึงสามารถใช้เพื่อเพิ่มการตรวจสอบสิทธิ์ แก้ไขข้อมูลอัตโนมัติ ทริกเกอร์อีเวนต์ภายนอก และลอจิกแบบคัสตอมอื่น ๆ ได้หลากหลาย

ข้อจำกัดและข้อควรระวัง

  • การจัดการผู้ใช้/สิทธิ์/สคีมาทั้งหมด ต้องแก้ไขไฟล์ CSV โดยตรง
  • ไม่เหมาะกับข้อมูลขนาดใหญ่ การแยกสิทธิ์ที่ซับซ้อน หรือสภาพแวดล้อมแบบกระจายที่ต้องการประสิทธิภาพสูง
  • ทำงานด้วยโค้ด Go มาตรฐานเท่านั้นโดยไม่มีไลบรารีภายนอก (มุ่งเน้นเพื่อการเรียนรู้/งานแบบง่าย)
  • ใช้ไลเซนส์ MIT และสามารถนำซอร์สโค้ดกับโครงสร้างไปใช้งานได้อย่างอิสระ
  • ยินดีรับการมีส่วนร่วม แต่ขอให้รักษา ความเรียบง่าย/ความชัดเจนของโค้ด โดยมีแผนจะดูแลโดยเน้นการแก้บั๊กมากกว่าการเพิ่มฟีเจอร์เพิ่มเติม

1 ความคิดเห็น

 
nemorize 2025-07-14

ว้าว...