Postmanのクラウド同期に疲れたエンジニアへ。GitでAPI定義を管理する「Bruno」のローカルファーストな実務運用
目次
開閉
Webアプリケーションやマイクロサービスの開発において、HTTPリクエストを手軽に組み立ててレスポンスを検証するAPIクライアントツールは、日々の開発に欠かせない相棒です。
長年、この分野のデファクトスタンダードといえばPostmanでした。私自身も黎明期のChrome拡張機能時代から10年以上にわたって現場で使い倒してきました。
しかし、ここ数年でPostmanに起きた変化に、小さくない戸惑いや違和感を抱えているエンジニアも多いのではないでしょうか。
無料プランでのアカウント登録必須化、ワークスペースのクラウド同期強制、そしてツール自体の多機能化に伴う起動の重さ。開発中の社内未公開APIや検証用のアクセストークンが、外部のクラウドサーバーに同期される運用に対して、セキュリティ規程やガバナンスの観点から頭を抱える現場も増えています。
そんな中、ここ最近現場で本格的に乗り換えて「まさに求めていたのはこれだ」と深く納得したのが、オープンソースのGitネイティブAPIクライアント Bruno (GitHub: usebruno/bruno)です。
今回は、なぜBrunoが現場のエンジニアに支持されているのか、その設計思想と実務での具体的なGit運用・CI連携のポイントを整理してご紹介します。
「クラウドDB」ではなく「ローカルファイル」に保存される思想
Brunoの最大の特徴であり、他のモダンAPIクライアントと決定的に異なる点は、「クラウドストレージを持たない完全なローカルファースト設計」 にあります。
Postmanなどのクラウド前提のツールでは、作成したコレクションやリクエストは運営元のクラウドデータベースに保存され、アカウント経由で同期されます。これに対してBrunoでは、コレクションを作成する際にローカルマシンの好きなディレクトリを指定します。
指定したフォルダの中に、コレクションの設定ファイルや各リクエストがプレーンテキストとしてそのまま保存される仕組みです。
my-api-project/
├── src/ # バックエンドのソースコード
├── tests/
├── bruno-collection/ # BrunoのAPIコレクション
│ ├── bruno.json # コレクション共通設定
│ ├── environments/ # 環境定義(local, stgなど)
│ │ ├── local.bru
│ │ └── stg.bru
│ └── users/ # 各エンドポイントのリクエスト定義
│ ├── get-users.bru
│ └── create-user.bru
└── package.json
この構造がもたらす恩恵は絶大です。「APIの動作検証用リクエストを、アプリケーションのソースコードと同じGitリポジトリに入れて一緒にバージョン管理できる」 ようになります。
実機検証:.bru ファイルの構造とGit運用の手触り
Brunoのリクエスト定義は、独自のプレーンテキスト形式である .bru という拡張子のファイルに保存されます。
実際に手元で作成した、ユーザー詳細取得APIの .bru ファイルの中身を見てみましょう。
meta {
name: ユーザー詳細取得
type: http
seq: 1
}
get {
url: {{baseUrl}}/api/v1/users/{{userId}}
body: none
auth: bearer
}
auth:bearer {
token: {{authToken}}
}
headers {
Accept: application/json
}
tests {
test("ステータスコードが200で返ること", function() {
expect(res.getStatus()).to.equal(200);
});
test("指定したユーザーIDと一致すること", function() {
const data = res.getBody();
expect(data.id).to.equal(bru.getEnvVar("userId"));
});
}
JSONやXMLのような冗長な形式ではなく、人間が目で見て直感的に理解できるシンプルなDSL(ドメイン固有言語)として設計されています。
この形式のおかげで、Gitでの変更管理が極めて快適になります。
たとえば、バックエンドの実装でAPIのレスポンス仕様を変更したり、新しいクエリパラメータを追加したりしたとします。その際、.bru ファイルを更新してコミットすれば、Pull Request(PR)の差分には以下のように表示されます。
get {
- url: {{baseUrl}}/api/v1/users/{{userId}}
+ url: {{baseUrl}}/api/v1/users/{{userId}}?include_profile=true
body: none
auth: bearer
}
レビュアーは「コードの実装差分」と「APIクライアントの呼び出し方の変更」を同じ画面で確認できます。
「コードはPRで上がってきたけれど、Postmanのコレクションは誰かが手動で更新して共有してくれるのを待たなければならない」というタイムラグや共有漏れが根本から解消されます。
また、Gitのブランチを切り替えれば、APIコレクションも手元のブランチの状態に合わせて自動的に過去や別の機能ブランチの状態へと巻き戻ります。並行して複数の機能ブランチを開発している現場では、これだけでも大きなストレス軽減になります。
現場で最も重要な「環境変数と機密情報」の分離設計
APIクライアントをGitで管理するにあたり、最も注意を払わなければならないのが 「認証トークンやAPIキーなどの機密情報をどう扱うか」 という点です。
Brunoでは、ベースURLや検証用パラメータを定義する「Environment」の仕組みが用意されています。
// environments/local.bru の例
vars {
baseUrl: http://localhost:8080
userId: usr_998877
}
このような公開しても問題ない一般的な環境変数は、そのまま .bru ファイルとしてGitにコミットしてチームで共有します。
一方、個人ごとのアクセストークンや外部サービスのAPIキーといった機密情報は、BrunoのGUI上で該当する変数を 「Secret」 としてマークします。
Secretに指定された変数は、.bru ファイル内には値が保存されず、Git管理対象外となるローカルストレージに分離して保持されます。
また、チームメンバー向けにはリポジトリ内に environments/local.example.bru や、必要なキーを一覧化した .env.sample を配置しておき、各自がローカルでシークレット値を埋める運用フローを敷くのが最も安全です。
CI/CDパイプラインとの統合:bru CLI による自動API回帰テスト
Brunoの魅力は、洗練されたデスクトップGUIにとどまりません。公式から提供されているCLIツール @usebruno/cli を使用することで、ターミナルやCI環境でそのままコレクションのテストを実行できます。
手元での実行はNode.js環境があれば簡単です。
# Bruno CLIのインストール
npm install -g @usebruno/cli
# コレクション配下のテストを一括実行
bru run bruno-collection --env local
テスト結果はターミナルに見やすく色分けして出力され、アサーションの成否やレスポンスタイムが即座に確認できます。
これをGitHub ActionsなどのCIワークフローに組み込むことで、PRが作成されるたびにAPIの自動回帰テストを回すパイプラインが簡単に完成します。
name: API Integration Tests
on:
pull_request:
branches: [main, develop]
jobs:
api-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Bruno CLI
run: npm install -g @usebruno/cli
- name: Start API Server
run: |
npm ci
npm run build
npm run start:test &
npx wait-on http://localhost:8080/health
- name: Run Bruno API Collection
run: bru run bruno-collection --env ci --env-var authToken=${{ secrets.TEST_API_TOKEN }}
PostmanでCI自動テストを行う場合、Newmanのセットアップやクラウド同期されたコレクションのエクスポート、有料プランのAPI利用枠を気にする必要がありました。
Brunoであれば、リポジトリ内にあるファイルを直接CLIで叩くだけなので、外部通信のレイテンシもなく、完全にクローズドなCI環境の中で高速にテストが完結します。
冷静な比較:Postmanを残すべき場面とBrunoへ移行すべき場面
ここまでBrunoのメリットを中心にお伝えしてきましたが、すべての場面においてPostmanを完全に排除できるわけではありません。ツールの適材適所を冷静に見極めることが重要です。
| 比較項目 | Bruno | Postman |
|---|---|---|
| データの保存場所 | ローカルファイルシステム(.bru) | 運営元クラウド(同期必須) |
| アカウント登録 | 不要(完全オフライン動作) | 基本必須(無料枠でも制限あり) |
| チーム連携方法 | Git(ブランチ、PR、マージ) | Postmanのワークスペース同期 |
| ライセンス | オープンソース(MIT) | プロプライエタリ |
| ドキュメント公開 | なし(Markdown等で別途管理) | 強力なWebポータル自動生成 |
| クラウドモック | なし(ローカルスクリプトで対応) | クラウド上に即座にモック公開可能 |
| エンタープライズ管理 | Gitホスティング(GitHub等)に依存 | 高度なRBAC・組織監査ログ |
Postmanが依然として適しているケース
- 公開APIを提供しており、外部開発者向けの美しいAPIリファレンスWebページを自動生成したい場合
- フロントエンド開発を先行させるため、クラウド上に手軽にモックサーバーを立てて社外パートナーと共有したい場合
- 数十人〜数百人規模の組織で、職種をまたいで(非エンジニアも含めて)APIカタログを一元管理したい場合
Brunoへ乗り換えるべきケース
- 社内向けWebサービスやマイクロサービスのバックエンド開発がメインの場合
- 認証情報や未公開エンドポイントを外部クラウドに預けられない、セキュリティ要件の厳しいプロジェクト
- APIの仕様変更をアプリケーションコードと同じブランチ・PRでレビューしたい場合
- 動作が軽快で、不要な機能のないシンプルな開発用クライアントを求めている場合
現場のバックエンドエンジニアやフルスタックエンジニアにとって、日々の実装と検証のテンポを最大化するという意味では、Brunoのローカルファーストな手触りは圧倒的な快適さをもたらしてくれます。
まとめ:データの主権を手元に取り戻す
GUIツールの進化は開発を便利にしてくれる一方で、過度なクラウド統合によって「自分のデータや設定がどこにあり、どう管理されているのか」が見えにくくなるストレスを生むことがあります。
Brunoが提示してくれた「API定義をプレーンテキストにし、開発者が使い慣れたGitで管理する」というアプローチは、新奇な技術というよりも、UNIX思想に通じるシンプルで健全な原点回帰だと感じています。
アカウント作成を求められることもなく、インストーラをダウンロードして起動すれば、すぐにローカルのディレクトリを選んで開発を始められます。日々のAPI検証フローに少しでも引っかかりを感じている方は、ぜひ手元の小さなプロジェクトから試してみてください。
なお、API定義がGit管理になると、ブランチごとの並行検証がより日常的になります。複数ブランチを切り替えながら開発を進める際の運用の工夫については、以下の記事もあわせて参考にしてみてください。