15P by xguru 2일전 | ★ favorite | 댓글 1개
  • 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/loginusernamepassword를 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 라이선스, 소스 코드 및 구조 자유 활용 가능
  • 기여는 환영하지만 코드 단순성/명료성을 유지하는 것을 지켜 줄 것. 더 이상의 기능 추가보다는 버그 수정 위주로 관리예정