🏌️‍♂️

バックエンドのコードだけで管理画面を作れるようにした話

に公開2

こんにちは、最近「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つの登場人物がいます。

  1. あなたのバックエンドサーバー (ここにSDKを用いて管理画面の関数を定義します)
  2. 中央のSourcetoolサーバー (認証・認可を担当する橋渡し役)
  3. ブラウザ (実際に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)
    }
}

これだけで、ブラウザからアクセスして使える管理画面ができます。フロントエンドのコードは一切書いていません。

https://www.youtube.com/watch?v=kk_BifRPVUA

とりあえず公開してみた

とりあえず、GitHubでオープンソースとして公開してみました。まだまだ発展途上ですが、同じ悩みを持つ人がいれば使ってみてください。セルフホストして無料で使えます。

自分が普段Goを書いているので、今のところGoのSDKだけですが、これからTypeScriptとPythonのSDKも作る予定です。(もしかしたらRustとかも作るかも)

もしなにかあれば、TwitterのDMでフィードバックもらえると嬉しいです。

ちなみに、ドキュメンテーションのMCPサーバーもあるので、Cursorなどに設定するとある程度ドキュメント読まなくてもAIが生成してくれます。

Discordコミュニティも立ち上げたので、質問や議論があればぜひ参加してください:Sourcetool Discord

Discussion

はがくん@元薬剤師のFlutter/Goエンジニアはがくん@元薬剤師のFlutter/Goエンジニア

いいですね〜、こういうのが欲しかったのでとても良いです👏

AkatsukiAkatsuki

ありがとうございます!そう言っていただけるととても嬉しいです!
もし使っていただける機会があれば、ぜひXなどでフィードバックをいただけると嬉しいです!