バックエンドのコードだけで管理画面を作れるようにした話
こんにちは、最近「Sourcetool」というものを作りました。自分が抱えていた問題を解決するために作ったツールなのですが、同じ悩みを持つ人がいるんじゃないかなと思って共有します。
バックエンド開発者の日常的な悩み
僕はバックエンドエンジニアです。データベースとやり取りして、ビジネスロジックを書いて、APIを実装するのは得意です。でも、管理画面を作るのは嫌いです。
なぜ管理画面を作るためだけに、複雑なフロントエンドのセットアップをしないといけないのか。単にデータを表示して編集したいだけなのにと常に思っています。
バックエンドの関数をそのまま呼びたい
バックエンド開発していると、DBにアクセスする関数などは自然に実装しますよね。これそのまま使いたくないですか?
例えばこんな感じで。
func usersPage(ui sourcetool.UIBuilder) error {
ui.Markdown("## Users")
name := ui.TextInput("Name", textinput.WithPlaceholder("Filter by name"))
// 既存のバックエンド関数をそのまま使える
users, err := listUsersByName(name)
if err != nil {
return err
}
// データをテーブルで表示
ui.Table(users)
return nil
}
これだけで動くUIが欲しかった。フロントエンドのコードを一切書かずにGoだけでUIを定義できて、しかも型安全な方法で。
AIの時代だからこそコードファーストがいい
最近はCursorやWindsurfといったAIツールを使って開発することが多くなりました。でもGUIベースのツールだとAIツールを最大限活用できません。
コードファーストならAIに「このページにボタンを追加して、クリックしたらこの関数を呼ぶようにして」とか言えば一発でやってくれる。バージョン管理も楽だし、コードレビューも普通にできる。
つまり、
- AIに説明・修正してもらいやすい
- 普段のGitワークフローに乗せられる
- コンパイルエラーで早期に問題が発見できる
こんなツールを作りたかったのです。
Sourcetoolの仕組み
Sourcetoolは非常にシンプルです。詳しくはDeepWikiに聞いてもらうと早いと思いますが、簡単に説明します。
Sourcetoolには3つの登場人物がいます。
- あなたのバックエンドサーバー (ここにSDKを用いて管理画面の関数を定義します)
- 中央のSourcetoolサーバー (認証・認可を担当する橋渡し役)
- ブラウザ (実際にUIを表示する場所)
この3者をつなぐのがWebSocketです。中央のSourcetoolサーバーが橋渡し役となって、ブラウザとあなたのバックエンドサーバーをリアルタイムにつなぎます。
例えばユーザーがブラウザでボタンをクリックすると、そのイベントはWebSocketを通じてあなたのバックエンドサーバーに伝わり、指定した関数が実行されます。そして関数の実行結果に基づいてUIが再レンダリングされるという仕組みです。
これによって「バックエンドのコードだけで完結する開発」が実現しています。
※Streamlitに影響を受けた設計となっていますが、Streamlitからデプロイの複雑性を排除しつつ、権限管理などの管理画面で必要な機能を標準装備しています。(権限管理機能はまだリリースしていませんが、今後リリースする予定です。)
実際にこんな感じで動きます
実際のSourcetoolはこんな感じで動きます。
func usersPage(ui sourcetool.UIBuilder) error {
ui.Markdown("## Users")
name := ui.TextInput("Name", textinput.WithPlaceholder("Filter by name"))
users, err := listUsersByName(name)
if err != nil {
return err
}
// データをテーブルで表示
ui.Table(users)
return nil
}
func main() {
st := sourcetool.New(&sourcetool.Config{
APIKey: "YOUR_API_KEY",
Endpoint: "wss://your-sourcetool-instance",
})
// ページを登録
st.Page("/users", "ユーザー管理", usersPage)
// サーバー起動
if err := st.Listen(); err != nil {
log.Fatal(err)
}
}
これだけで、ブラウザからアクセスして使える管理画面ができます。フロントエンドのコードは一切書いていません。
とりあえず公開してみた
とりあえず、GitHubでオープンソースとして公開してみました。まだまだ発展途上ですが、同じ悩みを持つ人がいれば使ってみてください。セルフホストして無料で使えます。
自分が普段Goを書いているので、今のところGoのSDKだけですが、これからTypeScriptとPythonのSDKも作る予定です。(もしかしたらRustとかも作るかも)
もしなにかあれば、TwitterのDMでフィードバックもらえると嬉しいです。
ちなみに、ドキュメンテーションのMCPサーバーもあるので、Cursorなどに設定するとある程度ドキュメント読まなくてもAIが生成してくれます。
Discordコミュニティも立ち上げたので、質問や議論があればぜひ参加してください:Sourcetool Discord
Discussion
いいですね〜、こういうのが欲しかったのでとても良いです👏
ありがとうございます!そう言っていただけるととても嬉しいです!
もし使っていただける機会があれば、ぜひXなどでフィードバックをいただけると嬉しいです!