Pennybase - 초경량 파일 기반 오픈소스 BaaS
(github.com/zserge)- Go 표준 라이브러리만으로 1,000줄 미만의 코드로 구현된 초소형 BaaS(Backend-as-a-Service)
- Firebase/Supabase/Pocketbase와 유사한 핵심 백엔드 기능을 로컬 파일 기반으로 제공
- CSV에 버저닝된 레코드를 사용한 파일 기반 데이터 저장
- JSON을 리턴하는 REST API
- 세션 쿠키와 Basic Auth 기반의 인증
- RBAC 및 소유자 기반 권한 시스템 지원
- 스키마 검증
- Go 템플릿 기반 템플릿 렌더링
작동 방식
-
데이터 저장
- 모든 데이터를 사람이 읽을 수 있는 CSV 파일에 한 행당 한 레코드씩 저장
- 첫 번째 컬럼은 레코드 ID, 두 번째 컬럼은 버전 번호로 고정
- 저장 방식은 append-only로, 기존 레코드를 덮어쓰지 않고 업데이트할 때마다 항상 새 버전 행을 추가
- 읽기 작업 시 항상 가장 최신 버전의 레코드만 사용
- 빠른 조회와 업데이트를 위해, 각 리소스별 최신 버전 레코드의 파일 오프셋 정보를 메모리 인덱스로 유지함
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로 사용자 생성이 불가하며, 반드시 파일을 직접 편집해야 함
- 사용자 인증 정보와 역할(Role) 목록은
-
권한 관리
- 리소스별 접근 제어 규칙을
_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
-
_schemas.csv
에 정의된 리소스(컬렉션)를 기반으로 REST API를 자동으로 제공 -
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}
: 해당 리소스의 서버-사이드 이벤트(SSE) 실시간 스트림 구독, "read" 권한 필요 -
인증 방식
- API 요청 인증은 Basic Auth 또는 세션 쿠키 방식 지원
- 세션 쿠키 생성:
-
POST /api/login
에username
과password
를 body에 담아 요청 - 응답에 세션 쿠키가 포함되어, 이후 요청 시 자동 인증
-
- 로그아웃:
-
/api/logout
호출 시 세션 무효화 및 쿠키 삭제
-
정적 파일 및 템플릿
-
static
디렉터리 내에 위치한 HTML, CSS, JavaScript 등 정적 파일을 직접 서빙할 수 있음- 예시:
static/index.html
파일을http://서버주소/index.html
로 접근 가능
- 예시:
- 추가로, Go의
html/template
패키지를 활용하여 HTML 템플릿 렌더링도 지원함- 템플릿 파일은
templates
디렉터리에 위치하며, URL로 접근 시 자동 렌더링 제공
- 템플릿 파일은
- 템플릿에서 사용할 수 있는 데이터 및 함수
-
.User
: 현재 인증된 사용자 정보(인증되지 않았으면nil
) -
.Store
: Pennybase의 스토어 인스턴스(리소스 조회, 목록화에 사용) -
.Request
: 현재 HTTP 요청 객체 -
.ID
: 접근 중인 리소스의 ID(해당되는 경우) -
.Authorize
: 특정 리소스에 대한 액션 권한을 확인하는 함수
-
훅(Hooks) 기능
- 단일 훅(hook) 함수로 동작을 확장할 수 있음
- 훅 함수는 모든 리소스의 생성(create), 수정(update), 삭제(delete) 작업 시 자동 호출됨
-
동작 원리
- 훅 함수는 아래 네 가지 인자를 받아 동작:
-
trigger
: 액션 종류(예: create, update, delete) -
resource
: 작업 대상 리소스명 -
user
: 요청을 수행하는 사용자 정보 -
res
: 변경되는 리소스 데이터
-
-
후킹 지점에서 추가 검증 또는 데이터 수정을 할 수 있음
- 예시처럼 메시지 리소스 생성 시 자동으로 author, 생성 시각을 입력
- 훅 함수에서 에러를 반환하면 해당 액션은 즉시 중단되며, 클라이언트에 에러 응답이 전달됨
- 이를 활용해 권한 추가 체크, 데이터 자동 보정, 외부 이벤트 트리거 등 다양한 커스텀 로직 구현 가능
- 훅 함수는 아래 네 가지 인자를 받아 동작:
제한 및 주의점
- 모든 사용자/권한/스키마 관리는 CSV 파일 직접 편집 필요
- 대규모 데이터, 복잡한 권한 분기, 고성능 분산환경엔 적합하지 않음
- 외부 라이브러리 없이 오직 표준 Go 코드만으로 동작(학습용/간이용 지향)
- MIT 라이선스, 소스 코드 및 구조 자유 활용 가능
- 기여는 환영하지만 코드 단순성/명료성을 유지하는 것을 지켜 줄 것. 더 이상의 기능 추가보다는 버그 수정 위주로 관리예정