Bruno

GitHub概要

usebruno/bruno

Opensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)

スター36,163
ウォッチ97
フォーク1,789
作成日:2022年9月27日
言語:JavaScript
ライセンス:MIT License

トピックス

api-clientapi-testingautomationdeveloper-toolsgitgraphql-clienthttp-clientjavascriptopenapiopenapi3opensourcerest-apitestingtesting-tools

スター履歴

usebruno/bruno Star History
データ取得日時: 2025/8/13 01:43

API開発ツール

Bruno

概要

Bruno(ブルーノ)は、プライバシーファーストを掲げるオープンソースAPIクライアントです。データは完全にローカルに保存され、GitフレンドリーなJSON形式でコレクションを管理できます。Postmanの有料化に対する開発者の反発を受けて2023年以降急成長を遂げ、オフライン重視・プライバシー保護の開発者に特に支持されています。

詳細

Brunoは、API探索とテストのためのオープンソースIDEとして開発されました。最大の特徴は、完全にオフラインで動作し、クラウド同期機能を意図的に提供しない「プライバシーファースト」設計です。従来のAPIクライアントがクラウドベースのデータ保存を採用する中、Brunoはユーザーデータをローカルデバイス上に保持することを重視しています。コレクション管理では、独自のBru形式のプレーンテキストマークアップ言語を使用し、リクエスト情報をファイルシステム上のフォルダに直接保存します。この設計により、Git等のバージョン管理システムとのシームレスな統合が可能で、チーム開発での差分確認やマージ操作が容易になります。APIリクエストの実行フローは、UI、Reduxストア、IPCブリッジ、メインプロセスが連携する洗練されたアーキテクチャを採用し、プリリクエストスクリプトやポストレスポンステストの実行も含む包括的なライフサイクルを提供しています。GraphQL、REST API、様々な認証方式(Basic、Bearer、OAuth)に対応し、Postman、OpenAPI、Insomniaからのインポート機能も充実しています。

メリット・デメリット

メリット

  • 完全プライバシー保護: データは一切クラウドに送信されずローカル保存
  • Git完全対応: プレーンテキスト形式でバージョン管理と差分確認が容易
  • オープンソース: MIT ライセンスで完全無料、カスタマイズ可能
  • 軽量高速: Electronベースだがパフォーマンスを重視した設計
  • 移行性: Postman、Insomnia、OpenAPIからの簡単インポート
  • チーム協働: Gitを使った自然なコラボレーション
  • 豊富な機能: GraphQL対応、スクリプト実行、コード生成など充実
  • クロスプラットフォーム: Windows、macOS、Linux対応

デメリット

  • クラウド同期なし: 意図的にクラウド機能を提供しない設計
  • 学習コスト: Git連携とBru形式の理解が必要
  • エコシステム小: プラグインや拡張機能がまだ限定的
  • 企業機能不足: チーム管理やエンタープライズ機能は限定的
  • 新興ツール: Postmanと比較して歴史が浅く、安定性で劣る場合

参考ページ

書き方の例

基本的なRESTリクエスト(Bru形式)

meta {
  name: Get User
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/users/{{userId}}
}

headers {
  Authorization: Bearer {{accessToken}}
  Content-Type: application/json
}

vars {
  userId: 12345
}

tests {
  test("Status is 200", function() {
    expect(res.status).to.equal(200);
  });
  
  test("User has email", function() {
    expect(res.body.email).to.be.a('string');
  });
}

POSTリクエストとJSONボディ

meta {
  name: Create User
  type: http
  seq: 2
}

post {
  url: {{baseUrl}}/users
}

headers {
  Authorization: Bearer {{accessToken}}
  Content-Type: application/json
}

body:json {
  {
    "name": "田中太郎",
    "email": "[email protected]",
    "age": 30,
    "department": "engineering"
  }
}

script:pre-request {
  // Pre-request script
  bru.setVar("timestamp", Date.now());
  bru.setVar("requestId", Math.random().toString(36));
}

script:post-response {
  // Post-response script
  if (res.body.id) {
    bru.setEnvVar("lastCreatedUserId", res.body.id);
  }
}

tests {
  test("User created successfully", function() {
    expect(res.status).to.equal(201);
    expect(res.body.id).to.exist;
  });
}

GraphQLクエリ

meta {
  name: GraphQL User Query
  type: graphql
  seq: 3
}

post {
  url: {{baseUrl}}/graphql
}

headers {
  Authorization: Bearer {{graphqlToken}}
  Content-Type: application/json
}

body:graphql {
  query GetUserProfile($userId: ID!) {
    user(id: $userId) {
      id
      name
      email
      posts {
        id
        title
        content
        createdAt
      }
    }
  }
}

body:graphql:vars {
  {
    "userId": "{{userId}}"
  }
}

tests {
  test("GraphQL query successful", function() {
    expect(res.body.data.user).to.exist;
    expect(res.body.data.user.email).to.include("@");
  });
}

環境変数設定(environments/)

// environments/development.bru
vars {
  baseUrl: https://api-dev.example.com
  accessToken: dev-jwt-token-here
  apiVersion: v1
}

// environments/production.bru
vars {
  baseUrl: https://api.example.com
  accessToken: prod-jwt-token-here
  apiVersion: v2
}

// environments/local.bru
vars {
  baseUrl: http://localhost:3000
  accessToken: local-test-token
  apiVersion: v1
}

認証フローとスクリプト

meta {
  name: OAuth Login
  type: http
  seq: 1
}

post {
  url: {{authUrl}}/oauth/token
}

headers {
  Content-Type: application/x-www-form-urlencoded
}

body:form-urlencoded {
  grant_type: client_credentials
  client_id: {{clientId}}
  client_secret: {{clientSecret}}
  scope: read write
}

script:post-response {
  // トークンを環境変数に保存
  if (res.body.access_token) {
    bru.setEnvVar("accessToken", res.body.access_token);
    bru.setEnvVar("tokenType", res.body.token_type);
    bru.setEnvVar("expiresIn", res.body.expires_in);
    
    console.log("Access token updated successfully");
  }
}

tests {
  test("OAuth token received", function() {
    expect(res.status).to.equal(200);
    expect(res.body.access_token).to.be.a('string');
    expect(res.body.token_type).to.equal('Bearer');
  });
}

Git連携の活用

# Brunoコレクションのバージョン管理
git init
git add .
git commit -m "Initial API collection setup"

# ブランチでの機能開発
git checkout -b feature/new-endpoints
# Bruno で新しいAPIエンドポイントを追加
git add api-collection/
git commit -m "Add new user management endpoints"

# チームでの共有
git push origin feature/new-endpoints
# Pull Requestでのレビュー後マージ

# 環境固有ファイルの除外
echo "environments/local.bru" >> .gitignore
echo "environments/secrets.bru" >> .gitignore