Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

REST API の操作

bca-web exposes the same analysis primitives as the bca CLI over HTTP. Use it when the consumer is a long-running service (an editor plugin, CI worker, or web app) that should not pay the cost of spawning the CLI per file. This page is a set of end-to-end curl calls, one per endpoint; the REST API reference documents every field.

Every endpoint is mounted under the /v1 prefix; the old unprefixed paths were removed at the 2.0 release (#637) and now return 404.

サーバーを起動する

bca-web --host 127.0.0.1 --port 8080 -j "$(nproc)"

Verify it is up:

curl -sf http://127.0.0.1:8080/v1/ping && echo "ok"
# => ok

/ping returns 200 OK with an empty body. curl -sf exits 0 on success and non-zero on any HTTP error, which is what scripts want.

ビルド、フラグや環境変数のチューニング、リソース制限、デーモン自体のセキュリティ態勢については、bca-web の運用 を参照してください。

インラインスニペットのメトリクスを計算する

curl -s http://127.0.0.1:8080/v1/metrics \
    -H 'Content-Type: application/json' \
    -d '{
          "id": "snippet-1",
          "file_name": "demo.rs",
          "code": "fn add(a: i32, b: i32) -> i32 { a + b }",
          "scope": "full"
        }' \
  | jq '.root.metrics'

scope: "file" はトップレベルのメトリクスのみを返します。"full"(デフォルト)はスニペット内のすべての関数・クラススペースを歩きます。サーバーは file_name から言語を推測するため、拡張子が重要です。

ディスク上のファイルのメトリクスを計算する

curl --data-binary plus jq packages a real file into the JSON envelope the server expects:

jq -nc \
    --arg id "$(uuidgen)" \
    --arg file_name "src/lib.rs" \
    --rawfile code src/lib.rs \
    '{id: $id, file_name: $file_name, code: $code, scope: "full"}' \
  | curl -s http://127.0.0.1:8080/v1/metrics \
      -H 'Content-Type: application/json' \
      --data-binary @- \
  | jq '.root.metrics.cyclomatic, .root.metrics.cognitive'

This pattern (jq -n --rawfile to build the request, curl --data-binary @- to stream it) avoids quoting problems with multi-line source code.

API 経由でコメントを除去する

エンドポイントは /comment(単数形)です。Content-Type で選択される 2 つのバリアントがあります:

  • application/json wraps the request and response in JSON. The response code field is a string holding the stripped source (the request code arrived as a JSON string, so the result is valid UTF-8; #629 replaced the earlier byte-array shape).
  • application/octet-stream accepts the source as the raw request body and returns the stripped source as the raw response body. This is the simpler variant to use from the shell.

octet-stream 形式(単発のシェル利用に推奨):

curl -s "http://127.0.0.1:8080/v1/comment?file_name=demo.py" \
    -H 'Content-Type: application/octet-stream' \
    --data-binary $'# leading comment\nprint("hi")  # trailing'
# => print("hi")

JSON form (use when your client speaks JSON natively):

curl -s http://127.0.0.1:8080/v1/comment \
    -H 'Content-Type: application/json' \
    -d '{
          "id": "strip-1",
          "file_name": "demo.py",
          "code": "# leading comment\nprint(\"hi\")  # trailing"
        }' \
  | jq -r '.code'

JSON レスポンスには送信した id がそのまま含まれるため、多数のリクエストを多重化するクライアントでも対応付けができます。

エディタプラグイン向けに関数スパンを抽出する

エンドポイントは /function(単数形)です:

curl -s http://127.0.0.1:8080/v1/function \
    -H 'Content-Type: application/json' \
    -d '{
          "id": "spans-1",
          "file_name": "demo.rs",
          "code": "fn a() {}\nfn b() {}\n"
        }' \
  | jq '.spans'

Each entry has name, start_line, and end_line; name is null when the parser could not resolve the function’s name (an anonymous or malformed definition). That is enough for an editor to draw a function navigator without re-parsing the file locally.

変更履歴リスクでリポジトリをランク付けする

/vcs エンドポイントは、サーバー側のファイルシステム上に既に存在する git 作業ツリーを分析し(変更履歴はリクエスト内で表現できません)、複合リスクスコアでランク付けしたファイル一覧を返します。シグナルと計算式のリファレンスは変更履歴(VCS)メトリクスを参照してください。

セキュリティ: 他のエンドポイントと異なり、/vcs はサーバー側の repo_path を受け取り、サーバープロセスが読み取れる任意の git リポジトリを走査して、そのリポジトリのファイルパスと変更シグナルを返します。認可レイヤーなしで /vcs を信頼できないクライアントに公開しないでください。デフォルトの 127.0.0.1 バインドであればローカルに閉じたままになります。

curl -s http://127.0.0.1:8080/v1/vcs \
    -H 'Content-Type: application/json' \
    -d '{
          "id": "risk-1",
          "repo_path": "/srv/checkouts/my-project",
          "top": 20
        }' \
  | jq '.files[] | {path, risk_score: .vcs.risk_score, churn_recent: .vcs.churn_recent}'

The body accepts the same knobs as bca vcs (long_window, recent_window, top, ref, risk_formula, file_types, full_history, include_merges, follow_renames, exclude_bots, bot_pattern, as_of, emit_author_details, author_hash_key, include_deleted, bus_factor_threshold, no_cache, cache_dir) as optional fields; top defaults to 50 like the CLI, and 0 returns every file. file_types scopes the ranking (metrics, the default, or all, or a rs,py-style extension list), mirroring the CLI --file-types. A repo_path that does not exist or is not a git working tree, or a malformed window / timestamp / formula / scope, returns 400 with the uniform JSON error body. Unknown fields are rejected with 400 too.

時系列トレンド

POST /vcs/trend samples the same metrics at several points in time and returns a per-file time series (see Historical trend). The body takes the /vcs fields except the cache controls (no_cache / cache_dir are rejected with 400, since trend does not cache) plus points (>= 2, default 12), span (default 12mo), and top_deltas (default 10; 0 returns all).

curl -s http://127.0.0.1:8080/v1/vcs/trend \
    -H 'Content-Type: application/json' \
    -d '{
          "id": "trend-1",
          "repo_path": "/srv/checkouts/my-project",
          "points": 12,
          "span": "24mo",
          "top": 20
        }' \
  | jq '.deltas.regressed[] | {path, delta}'

ポイント数が 2 未満(またはサポートされる上限を超える場合)は、他の不正リクエストの場合と同様に、統一 JSON エラー本文とともに 400 が返ります。

ジャストインタイムのコミット / diff スコアリング

POST /vcs/jit は単一のコミットをスコアリングします(ジャストインタイムスコアリングを参照)。本文には repo_path、commit(デフォルト HEAD)と、long_window / recent_window / full_history / include_merges / follow_renames / as_of の各調整項目を指定します。エコーバックされた id を含むコミットの JitReport JSON が返ります。

curl -s http://127.0.0.1:8080/v1/vcs/jit \
    -H 'Content-Type: application/json' \
    -d '{ "id": "jit-1", "repo_path": "/srv/checkouts/my-project",
          "commit": "HEAD" }' \
  | jq '{risk_score, purpose: .commit.purpose}'

To score an arbitrary diff instead, send a diff field carrying the unified diff (no repo_path needed). The response is then the partial report: source: "diff", a partial_risk_score, and no history / experience / purpose groups, which are absent rather than zero. The partial score is not comparable to a commit score.

git diff | jq -Rs '{id: "jit-diff", diff: .}' \
  | curl -s http://127.0.0.1:8080/v1/vcs/jit \
      -H 'Content-Type: application/json' -d @- \
  | jq '{source, partial_risk_score}'

不正な diff(あるいは解決できない commit、git 作業ツリーでない repo_path)を指定すると、統一 JSON エラー本文とともに 400 が返ります。

CI から API を呼び出す

For a short-lived CI job, start the server as a background process and stop it when the job finishes:

bca-web --port 8080 &
SERVER_PID=$!
trap 'kill "$SERVER_PID"' EXIT

# 起動するまで待ちます。
until curl -sf http://127.0.0.1:8080/v1/ping >/dev/null; do sleep 0.1; done

# … ここで分析の呼び出しを実行します …

For longer-lived workers, run the server as a systemd unit (or a container) and point your jobs at its host and port.