世界を動かす技術を、日本語で。

貧者のバックエンド・アズ・ア・サービス(BaaS):Firebase/Supabase/Pocketbaseに類似

2025年7月4日原文(github.com)

概要

Pennybase は、 軽量なBaaS として、 Firebase/Supabase/Pocketbase の代替となるGo製ソリューション。 標準ライブラリのみ で実装され、ファイルベースの CSVストレージ を採用。 認証・RBAC・リアルタイム更新 などの基本機能を1000行未満で実現。 REST API やテンプレート描画、フックによる拡張性も確保。 MITライセンス で公開、シンプルさ重視の設計。

Pennybaseの特徴

  • Firebase/Supabase/Pocketbase のようなBaaS機能を Go言語 で実装
  • 外部依存なし・標準ライブラリのみ で動作
  • CSVファイル による バージョン管理付きストレージ 方式
  • REST API でCRUD操作・リアルタイム更新の提供
  • 認証(セッションCookie/Basic認証)RBAC/所有権ベースの権限管理
  • スキーマバリデーション (数値/テキスト/リスト型対応)
  • Goテンプレート によるHTMLレンダリング
  • フック関数 で拡張性確保
  • 静的ファイル配信 機能

データ構造・ストレージ

  • データはCSVファイル に1レコード1行で保存
  • 追記専用設計 で各更新は新バージョンとして保存
  • 最新バージョンはメモリ上のインデックス で高速アクセス
  • 1列目:レコードID、2列目:バージョン番号、以降はデータ項目
  • _schemas.csv でJSONフィールドとCSVカラムのマッピング・バリデーション定義
    • 型は text/number/list のみ対応
    • バリデーションに 正規表現 や最小/最大値指定

ユーザー・認証管理

  • _users.csv で認証情報・ロール管理
    • ユーザーID(ユーザー名)・バージョン・ソルト・パスワード(SHA-256+Base32)・ロール
  • API経由でユーザー追加不可、手動編集のみ
  • 認証方式Basic認証 または セッションCookie
    • /api/login でセッション生成、 /api/logout で無効化

権限管理(RBAC)

  • _permissions.csv でアクセス制御ルール定義
    • リソース名・アクション・フィールド・許可ロール 等を指定
    • owner フィールド指定で所有者も許可
  • ルール不一致時はアクセス拒否

REST APIエンドポイント

  • GET /api/{resource}?sort_by={field} :リスト取得・ソート可
  • GET /api/{resource}/{id} :単一レコード取得
  • POST /api/{resource} :新規作成("create"権限必要)
  • PUT /api/{resource}/{id} :更新("update"権限必要)
  • DELETE /api/{resource}/{id} :削除("delete"権限必要)
  • GET /api/events/{resource} :SSEによるリアルタイム更新配信("read"権限必要)

静的アセット・テンプレート

  • staticディレクトリ からHTML/CSS/JS等の静的ファイルを配信
  • templatesディレクトリ でGoテンプレートを利用可能
    • テンプレート内で .User, .Store, .Request, .ID, .Authorize 等の変数/関数が利用可
    • 権限チェック やレコード取得もテンプレート内で柔軟に実装

拡張フック(Hooks)

  • create/update/delete時に1つのフック関数 を呼出
    • trigger:アクション種別、resource:リソース名、user:実行者、res:操作対象データ
    • 追加バリデーションやデータ加工 が可能
    • エラー返却でアクション中断

コントリビューション・ライセンス

  • MITライセンス で公開
  • バグ修正・テスト・例のみ歓迎、新機能追加は原則なし
  • シンプル・明快・正確なコード維持が方針

Pennybaseの活用シーン・メリット

  • 小規模プロジェクトやプロトタイピング 用途に最適
  • 外部DBや複雑な依存不要 で導入が容易
  • シンプルなRBAC/認証/ストレージ を短時間で構築可能
  • Go言語学習・BaaS仕組み理解 にも有用

まとめ

  • Pennybase超軽量・依存ゼロ のBaaSで、 CSV+Goのみ で本格的なバックエンド機能を実現
  • 認証・RBAC・リアルタイム・テンプレート 等、必要十分な機能を1000行未満で実装
  • シンプル設計拡張性 の両立が特徴
  • MITライセンス で自由に利用・改変可能

Hackerたちの意見

このアプローチのシンプルさが好きだな。目的のためにtrailbaseをフォローしてるよ: https://trailbase.io 簡単なバックエンドの選択肢がいろいろ出てきてるのが嬉しい。pennybaseからtrailbase、pocketbaseまで。どれかが最終的にsqliteの代わりにpostgresを実装してくれるといいんだけどね。

Pocketbaseに貢献する代わりに新しいプロジェクトを作る理由がわからない。Pocketbaseと似てるのに、何が新しいの?

ミニマリズム。小さくて、データはvimsha256sumで完全に管理できる。設定を考えると、ユーザーリストが数十人の小規模な家庭用アプリには合ってると思う。

なんで?ってずっと思ってたけど、結局は著者の選択なんだよね。私たちはそれを二者択一として考えがちだけど、実際にはこれか何もないという選択肢だったのかもしれない。あなたの投稿の二行目が好きなんだけど、比較はどうなの?私の意見では、これが本当に小さい(1k loc未満はすごい)ってことが一番のポイントかも。もしかしたら、オッカムの剃刀に従ってSQLを捨てて、最もシンプルなSQL(SQLite)も完全に無視して、CSVにしたのかも。SQLiteが一番シンプルで埋め込み可能なSQLデータベースだと思ってたから、こんなことを言う日が来るとは思わなかった。ちょっと脱線しちゃったかもしれないけど、SQLiteとPocketbaseのやってることが本当に好きなんだ。SQLiteとユーザごとのデータベースを考えると、このアーキテクチャについて考えるだけで幸せになるよ。SQLiteが大好き!

Pocketbaseにはないものを何をもたらすの? NIHが主な理由だね。PocketBaseが優れている大きな理由は、機能や貢献が厳しく制限されているからだと思う。みんなにはエコシステムに貢献してほしいな。エコシステムは大きくて成長してるから。

公平に言うと、このプロジェクトは最近書いたブログ記事にリンクされてるから、ほんとに小さな個人的/教育的なプロジェクトなんだ。k8sのAPIサーバーが提供するようなAPIを試してみたくて、カスタムリソースの動的スキーマ、均一なREST APIの生成、明確に定義されたRBACルール、ウォッチ/リアルタイム通知、入場フックでのビジネスロジックのカスタマイズなどを実験したよ。できるだけ小さくしようともしたしね。だから、Pocketbaseや他のものと競争するつもりはないんだ。ただ、似たようなアーキテクチャでミニマムなバックエンドを構築するには何が必要かを見てみたいだけなんだ。「データベース」の選択は、まさにその目標によって決まってる。意図的にインターフェースにしたから、もっと良いデータベースも存在するし、少しのコード変更で接続できるよ。でも、最初はGoの標準ライブラリが提供するものを使ったし、CSVはデバッグが簡単だからね。

なんでハウスシェアに参加せずに、自分の家を買ったり借りたりするの?

Chromeがデスクトップとモバイルの両方でFile System Access APIをサポートするようになった今、バックエンドってまだ必要かな?ユーザーデータをファイルとして保存するウェブアプリを書き始めたけど、このアプローチがすごく気に入ってる。デスクトップとAndroidでは完璧に動くよ。iOSは本物のChromeが使えないから(たぶんヨーロッパだけ)、データを「Origin private file system」に保存するオプションも用意してる。幸い、同じAPIを使えるから実装も楽だった。唯一の欠点は、ユーザーが選んだディレクトリにファイルを置けないこと。だから、そのモードでは古典的なダウンロードリンクでバックアップをサポートしてる。これで、ユーザーはデータをクラウドに入れなくて済むし、全部自分のデバイスに残るよ。

TIL!クラウドなしのアプリを作るのが好きで、「エクスポート」ボタンを使ってローカルストレージに依存してる。このアプローチがまさに探してたものだ。ローカルファーストのアプリについて読んだことの多くは、コラボレーション機能のためのデータ同期を解決することを含んでたけど、ローカルの永続性だけが必要ならこんなにシンプルだとは思わなかった。

複数のデバイスやブラウザを使ってる人はどうなるの?ローカルストレージを何年も使ってるけど、特にマルチプレイヤーでは導入が難しくなってるよね。

Chromeがデスクトップとモバイルの両方でFile System Access APIをサポートしている今、バックエンドはまだ必要なのかな?これでローカルDBにアクセスできるようになるのかな?アプリが自分のデバイスにあるDBと直接やり取りできるようになって、デバイス間でDBが同期できるといいな。そうすれば、すべてのデバイスでデータを持っていられるけど、データは常に自分のデバイスの中に留まるからね。もちろん、これはネイティブアプリでやるのは比較的簡単だけど、ブラウザ上で動くWebアプリでもできるといいな。ところで、Chromeはログインしているときにローカルストレージをデバイス間で同期するの?

少なくともAndroidの面では、アプリが自分のストレージターゲットに書き込めるようにしてほしいな。理由は、すでにSyncthing-Forkを使って親Syncディレクトリ(ObsidianやOpenTracksなど)を監視して、バックアップシステムに送ってるから。実際、これによりアプリがローカルファーストになって、ネットワークアクセスなしでも動けるようになるんだ。でも、自動バックアップはできるようにしたい。もしこれをもう少し形式化するものがあれば、開発者もアプリを「自分のネットワークを持ち込む」みたいな感じで作れるかも。もしかしたら、すでに誰かがやってるかもしれないね。

Hacker Newsで議論の続きを見る