移行と廃止のタイムテーブル
/api は新しいプロトコルではなく、既存のドメインサブ契約を同じプレフィックス、同じエンベロープの下に集めたものです。したがって移行の主な作業はパス、ヘッダー、エラー判定の置き換えであって、業務ロジックの書き直しではありません。成功レスポンス本文とイベントペイロードは 1 バイトも変わりません。
旧プレフィックスと /api の対応はマニフェストの各操作の legacyPath / legacyOffloadPath フィールドに登録されています。よく使うものを挙げます。
| 旧パス | /api |
備考 |
|---|---|---|
POST /v2/sessions |
POST /api/sessions |
セッションファミリー sdk1(既定) |
POST /v3/sdk2/sessions |
POST /api/sessions + tansr-session-family: sdk2-offload-v1 |
パスは同じで、ファミリーはリクエストヘッダーが宣言する |
GET /v2/sessions/:id/events |
GET /api/sessions/:id/events |
交渉ヘッダーなしならフレームはバイト単位で同一 |
POST /v2/sessions/:id/permission/:requestId |
POST /api/sessions/:id/permission/:ticketId |
プレースホルダー名が :ticketId に変更(:id は引き続きセッション id) |
POST /v1/approvals/:id/credential |
POST /api/approvals/:id/credential |
/v1 から移された唯一の操作(0.14.0) |
GET /v3/sdk2/session-capabilities |
GET /api/capabilities/sessions?protocol=sdk2-ext-v1 |
|
GET /v3/sdk2/capabilities |
GET /api/capabilities/archive |
クエリ文字列なし |
POST /v3/sdk2/bindings |
POST /api/archive/bindings |
|
GET /v3/sdk2/bindings/:id |
GET /api/archive/bindings/:id?protocol=sdk2-ext-v1 |
GET 読みは protocol を付ける |
POST /v3/sdk2/bindings/:id/archive/acks |
POST /api/archive/bindings/:id/archive/acks |
|
POST /v3/sdk2/archive-sync/:id |
POST /api/archive/sync/:id |
エラー本文は引き続き archive-sync-v1 の元のエンベロープ |
GET /v3/sdk2/cache/capabilities |
GET /api/capabilities/cache |
|
POST /v3/sdk2/cache/bindings |
POST /api/cache/bindings |
|
POST /v2/executors/connections |
POST /api/executors/connections |
|
GET /v3/terminal/capabilities |
GET /api/capabilities/terminal?contract=terminal-services-v1 |
|
POST /v3/terminal/bindings |
POST /api/terminal/bindings |
|
GET /v3/terminal/sessions/:id/tool-output |
GET /api/terminal/sessions/:id/tool-output?contract=…&sessionContract=… |
|
GET /v3/terminal-observation/sessions/:id/resources |
GET /api/terminal/observation/sessions/:id/resources |
プレフィックスのセグメントが terminal/observation に |
GET /v3/terminal-profile/sessions/:id/catalog |
GET /api/terminal/profile/sessions/:id/catalog |
プレフィックスのセグメントが terminal/profile に |
この表を手で保守しないでください。公式クライアントのパスモジュールはマニフェストから生成されており、自分でクライアントを書くときも GET /api/manifest またはリポジトリ内の api-manifest.json から生成すべきです。
リクエストとエラー形の違い
Section titled “リクエストとエラー形の違い”| 観点 | 旧プレフィックス | /api |
|---|---|---|
| セッションファミリー | パスで区別(/v2 と /v3/sdk2) |
パスは同じで、リクエストヘッダー tansr-session-family |
| サブ契約のリビジョン | 一部はパスや本文に | GET の読みとストリームはクエリ文字列 protocol= / contract=、書き操作はクエリ文字列を受け付けない(唯一の例外:session.checkpoint.import の label) |
| レスポンスヘッダー | 統一ヘッダーなし | すべてのレスポンスが tansr-contract / tansr-manifest-revision / tansr-domain / tansr-schema-hash を持つ |
| エラー本文 | { error: { code, message, detail? } }、コードは各ファミリーの語彙 |
8 キーの統一エンベロープ。code は 19 の統一コードで、ファミリーコードは detail.domainCode に下がる |
| 一部エラーのステータス | session_ended 409、binding_closed 409、unsupported_capability 422 / 409 |
410 gone、410 gone、404 capability_unavailable(元のステータスは detail.domainStatus) |
| イベントフレーム | 各ドメインの元のフレーム | 交渉ヘッダーなしなら同一。tansr-event-envelope: unified-v1 を付けると 7 キーのエンベロープ |
| 冪等 / 条件付き書き込み / 期限 | 本文内の requestId / expectedRevision だけ |
さらに Idempotency-Key / If-Match / deadline ヘッダーが使える(0.14.0 以降)。サーバーが本文内の位置に写す |
| 2xx レスポンス本文 | — | バイト単位で同一 |
移行で最も見落としやすいのはエラー判定です。error.code === 'session_ended' のような分岐を統一コード gone での判定に改め、retryAction で動作を決め、細かく分けたいときにだけ detail.domainCode を読んでください。詳しくは統一リクエストヘッダー、レスポンスヘッダーとエラーエンベロープを参照してください。
セッションサービスの /v1
Section titled “セッションサービスの /v1”セッションサービスのプロセス内にある /v1(/v1/status、/v1/sessions ファミリーなどのシングルテナント Bearer ルート)と /api は 2 つの別々のアイデンティティ体系で、/api の下にそれらの対応物はありません。@tansr/serve 0.13.0 以降は次のとおりです。
/apiを組み込んだデプロイでは/v1が既定でオフです。ライブラリ形態でstartServer({ v2: … })を使うとdisableV1の既定はtrueになり、/v1*へのリクエストは 404 を受け取ります。CLI 形態のtansr serve --v2も同じです。- 移行期間の維持:ライブラリには
disableV1: falseを渡します。CLI では--legacy-v1を付けるか、環境変数TANSR_SERVE_LEGACY_V1=1を設定します(フラグが環境変数より優先)。 --v2を付けない SDK1 だけのtansr serveには/apiがなく、影響も受けません。/v1はこれまでどおりです。@tansr/serve0.14.0 と@tansr/cli0.10.1(2026-10-04)は--legacy-v1/TANSR_SERVE_LEGACY_V1を非推奨にしました。引き続き有効ですが、起動時に非推奨の告知が出ます。これは独立した廃止項目で、取り除く時点は 1.0.0 より前に別途告知されます。
このサイトの REST リファレンスにある /v1 はプラットフォーム側のインターフェースで、ここで述べたセッションサービスの /v1 とは無関係です。
6 ステップの移行と現在の進み具合
Section titled “6 ステップの移行と現在の進み具合”| ステップ | 内容 | @tansr/serve 0.15.1(2026-10-10 公開、現行 npm latest)時点の状況 |
|---|---|---|
| 1 | 内部アダプター:/api が書き換えて既存のドメインハンドラーに委譲し、旧プレフィックスはバイト単位で不変 |
完了(0.13.0) |
| 2 | 二重書き込み / シャドウ読み取り:同じゴールデンベクターを旧入口と /api の両方で走らせ、成功本文はバイト単位で同一、エラー本文はフィールド単位で同じ出所 |
Node と .NET には同一出所の対応表と適合性リプレイがある。Android / iOS / HarmonyOS / Go は 165 本のゴールデンベクターのリプレイで整合 |
| 3 | クライアントの切り替え:各クライアントのソースに旧プレフィックスのリテラルが残らない | Node @tansr/api-client 0.3.0 正式版は切り替え済み(./api)。0.4.0(2026-10-06)から、routePrefixes を渡さない凍結済み ./sdk2 と ./terminal も既定で /api です。旧プレフィックスが必要なら LEGACY_ROUTE_PREFIXES を明示します。./api 入口は 0.3.0 から不変です。.NET NuGet 0.2.0、Go github.com/tansrai/tansr-go v0.3.0、Rust / Python / C++ 0.1.0 は公開パッケージで /api に載っています。Android、iOS、HarmonyOS のリリース状況は各言語のクライアントを参照。examples/serve-demo は公開 SDK 経由に変更 |
| 4 | 新旧混用の禁止:同じセッションファミリーが 2 種類のプレフィックスで交差アクセスされたら構造化された警告を出す(拒否はしない) | 0.15.0 で開始。同一セッション id が /api と /v2 または /v3/* の両方から使われると、構造化ログ api.legacy_prefix_mixed を出します。既定の readwrite では拒否しません |
| 5 | 旧入口の読み取り専用ウィンドウ:/v2、/v3/* の書き操作は 410 を返し、読みは引き続き受け付け、レスポンスに廃止ヘッダーを付ける |
切り替えは 0.15.0 で入りました。既定は readwrite のままなので、書き操作は 410 になりません。TANSR_SERVE_LEGACY_PREFIX=readonly で読み取り専用ウィンドウを開けます。off は旧プレフィックスをすべて 404 にします。旧プレフィックスの応答には Deprecation と Link が付き、TANSR_SERVE_LEGACY_SUNSET を置くと Sunset も付きます。0.15.0 の公開ノートは、後の版で既定を readonly にすると書いてあります。現行 npm の @tansr/serve 0.15.1(2026-10-10)は既定の readwrite を保ち、その移行は入っていません。0.16.0 は未公開です |
| 6 | クローズ:/v2、/v3/* の外部から到達できる入口を取り除き、旧プレフィックスは統一エンベロープの 404 を返す |
1.0.0 |
セルフホストの複数レプリカ構成では、ステップ 3 の前にリバースプロキシを調整する必要があります。/api/sessions/:id/** は /v2/sessions/:id/** と同じシャードアフィニティで流し、/api の下の 4 本の SSE パスは同じ長時間接続の規律に従わせてください。そうしないと切り替え後にレプリカをまたいだ 404 が起きます。
廃止のタイムテーブル
Section titled “廃止のタイムテーブル”| マイルストーン | リリース | 公開契約の変化 |
|---|---|---|
| 2026-10-02 | @tansr/serve 0.13.0、@tansr/protocol 0.2.0、@tansr/cli 0.10.0 |
/api が正式に利用可能。/api を組み込んだデプロイで /v1 が既定でオフ。/v2、/v3/* の 1.0.0 での廃止を予告 |
| 2026-10-04 | @tansr/serve 0.14.0、@tansr/cli 0.10.1、@tansr/api-client 0.3.0 |
マニフェスト revision 7、3 つのリクエストヘッダー。--legacy-v1 を非推奨に |
| 2026-10-06 | @tansr/serve 0.15.0、@tansr/cli 0.10.2、@tansr/api-client 0.4.0 |
ステップ 4 の警告は有効で、既定では拒否しません。ステップ 5 の読み取り専用ウィンドウは明示して開け、既定は readwrite のままです。旧プレフィックスの応答に Deprecation / Link が付きます。凍結された api-client 入口は既定で /api へ出ます |
| 2026-10-10 | @tansr/serve 0.15.1、@tansr/cli 0.10.3 |
旧プレフィックスのウィンドウは既定の readwrite のままです。統一エラーエンベロープのマッピングを 2 か所修正——マトリクスに登録されていないドメインコードは一律 500 internal_error、result_unknown の retryAction は query-status / rebind に絞られます。マニフェスト、パス、成功ボディは変わりません |
| 1.0.0 | @tansr/serve 1.0.0、@tansr/api-client 1.0.0 |
/v2、/v3/* の外部入口を取り除き、/api が唯一の呼び出し面になる。unified-v1 ファミリーが candidate から frozen に。@tansr/api-client の SDK1 エントリが非推奨になり、2.0 で削除 |
/v1 のオフと /v2、/v3/* の廃止は 2 つの独立した公開契約の変更で、それぞれにリリースノートがあります。
ペアでのロールバック
Section titled “ペアでのロールバック”- サーバーのロールバックはクライアントとペアでなければなりません。 0.12.0 には
/apiがありません。/apiに切り替え済みのクライアントはtansr-contractヘッダーのない旧形の 404 を受け取り、規律に従って「契約が利用できない」と報告し、自動では旧プレフィックスに戻りません。サーバーを 0.12.0 に戻すときは、Node は@tansr/api-client0.2.0 と旧入口に戻し、モバイルは 1 つ前のリリースに戻してください。 - クライアントは単独でロールバックできます。 0.13.0、0.14.0、0.15.0、0.15.1 のサーバーは既定の
readwriteで/v2、/v3/*を保持しており、古いクライアントにプロトコルの断絶はありません。これは 1.0.0 の前まで保たれます。TANSR_SERVE_LEGACY_PREFIXをreadonlyまたはoffにすると、そのモードに合わせて古いクライアントの書き、または旧プレフィックス全体が拒否されます。 - 0.13.0 と 0.14.0 にストレージ形式の変更はありません。セッションストア、アーカイブホスト、キャッシュ媒体はロールバック中に移行を必要としません。0.15.x の旧プレフィックスウィンドウのつまみを
readwriteに戻す場合も、データの変更はありません。 - リバースプロキシのテンプレートとクライアントの切り替えは同じ方向に動かす必要があります。クライアントが
/apiに切り替え済みなのにテンプレートを戻すと、シャードアフィニティが失われます。
Node クライアントのエントリ移行
Section titled “Node クライアントのエントリ移行”@tansr/api-client 0.3.0 は 4 つの旧エントリ ./sdk2、./sdk2/node、./terminal、./terminal/node を凍結し(パッケージとともに配布、変更なし、削除なし)、./api を追加しました。移行の推奨手順:
- 新しいコードは必ず
import { createApiClient } from '@tansr/api-client/api'を使い、操作名で呼び、パスを組み立てません。 - 旧エントリの呼び出し箇所を操作名ごとに
api.call(...)へ移します。アーカイブ / キャッシュ / ターミナルの GET 読みではprotocol/contractを手で埋める必要はなく、SDK が操作ごとに既定のリビジョン値を注入します。 - エラー処理をファミリーコードから統一コード +
retryActionに改め、必要ならerror.domainCodeを読みます。 - 同じプロセス、同じセッションファミリーの中で新旧エントリを併用しないでください。それこそがステップ 4 で警告される「混用」です。
このページは役に立ちましたか?
フィードバックありがとうございます。この記事の改善に活かします。