- 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로 사용자 생성이 불가하며, 반드시 파일을 직접 편집해야 함
-
권한 관리
- 리소스별 접근 제어 규칙을 _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 등 정적 파일을 직접 서빙할 수 있음
- 추가로, 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 라이선스, 소스 코드 및 구조 자유 활용 가능
- 기여는 환영하지만 코드 단순성/명료성을 유지하는 것을 지켜 줄 것. 더 이상의 기능 추가보다는 버그 수정 위주로 관리예정