検索/公式SDKとCLIがそのまま動く、ローカルのクラウドエミュレーターを作る

公式SDKとCLIがそのまま動く、ローカルのクラウドエミュレーターを作る

クラウドの動きを手元のPCでまねるエミュレーターに、サービスや操作を足す時に使う。まず本物の通信プロトコルを調べ、要求と応答の形を本物のクラウドと同じに保ち、保存方式と設定を一緒に直し、公式SDKを使ったテストで確かめてからリリースへ進める。

このAIルールを使うには
## 本物のクラウドと同じ要求と応答の形を、楽さより優先する 次の順で優先する。 1. 上流クラウドプロトコルとの互換性 2. 公式SDKとCLIクライアントが期待する挙動 3. 既存エミュレーターのパターン再利用 4. 実装上の都合より正確性 5. 範囲が狭く、テスト可能な変更 実装を楽にするために独自のエンドポイント形式を追加したり、要求と応答の形式を簡略化したりしない。依頼された挙動に必要でない限り、広範なリファクタリングを行わない。 編集前に、対象サービス、管理プレーンかデータプレーンかという役割、プロトコル群、手本にする既存実装、設定への影響、保存領域への影響、文書への影響、最小限で有効なテスト計画を特定する。 挙動が不明確な場合は、上流プラットフォームの契約、確立済みのエミュレーター挙動、互換性テスト一式の期待値の順で優先する。タスクがサービス横断のアーキテクチャ変更を必要とする場合は、考えずにリファクタリングせず、利点と不利益を明示する。 ## プロトコルを扱う部分は薄くし、業務ロジックはサービスに置く サービスを次の層に分けて設計する。 - コントローラーまたはハンドラーはプロトコル入力を解析し、プロトコル互換の応答を作る。 - サービスは業務ロジックを保持し、共有のクラウドドメイン例外を送出する。 - モデルはドメインデータを表す。 - レジストリ、設定、保存領域ファクトリー、ライフサイクルサービス、パーサー、ビルダー、例外マッパーは共有基盤を提供する。 コントローラーは薄く保つ。新しいパターンを導入する前に、共有ユーティリティを再利用し、最も近い既存サービスの構造を踏襲する。 ドメイン障害は共有の例外型を通す。クエリとXMLの処理系は標準の例外マッパーを使い、JSONプロトコルの処理系は要求された構造化エラー本文を返す。コントローラーの戻り値型は、事前コンパイル時のリフレクションとシリアライズの制約に適合させる。 コンストラクター注入を使い、条件文には波括弧を付け、コードだけで意図が分かるようにする。catchブロックを空にしてはならない。例外を意図的に許容する場合は、診断に十分な文脈をログへ記録する。 ## 操作を足す前に、そのサービスの本当のプロトコルを調べる 操作を追加する前に、実際の通信プロトコルを特定する。 - クエリプロトコルはフォームエンコードされたアクションとXML応答を使う。 - JSON RPC形式のプロトコルはターゲットヘッダーと構造化JSONを使う。 - REST JSONとREST XMLは、リソースパスとそれぞれ固有の本文形式を使う。 - データプレーンのサービスでは、HTTP管理APIではなくネイティブTCPプロキシが必要になる場合がある。 共有のXMLビルダー、パーサー、名前空間定数を使う。正規表現でXMLを解析してはならない。JSONエラーは対象プロトコルのエラー構造へ合わせる。 複数の互換経路を提供するサービスもある。代替ハンドラー同士の挙動を揃え、一緒にテストする。ID検出エンドポイントは、管理APIモデルへ無理に通さず、本来のオープンプロトコルとして扱う。 管理APIは、手作りのHTTP要求だけでなく、公式SDKクライアントを通して検証する。手作りのペイロードを受け付けたことだけでは、クライアントのシリアライズ、ヘッダー、エラー、ページ分割、URL生成との互換性を証明できない。 ## 保存方式と設定ファイルを、いつも一緒に直す 保存領域には共有ファクトリーと宣言済みの方式を使う。サービス内で保存実装を直接生成してはならない。読み込み、フラッシュ、チェックポイント、先行書き込みなどのライフサイクルフックを守る。 インターフェースの既定値とデプロイ済みの値が異なる場合は、リポジトリの実行時設定ファイルを実効上の正本として扱う。 保存関連の挙動では、次を行う。 1. 正本となる設定インターフェースを更新する。 2. 主な実行時設定を更新する。 3. テスト設定を更新する。 4. 保存領域ファクトリーを通して方式を接続する。 5. ライフサイクル統合を検証する。 利用者が扱う設定については、文書も更新し、確立済みの環境変数命名規則に従う。生成される識別子やエンドポイントへ影響する場合は、基底URL、ホスト名、リージョンとアカウントの既定値、ポート範囲、永続化ルート、コンテナネットワークを確認する。 新しいフィールドは互換性を保って追加し、共有設定、保存領域、サービス登録を同期させる。 ## 手作りの要求ではなく、公式SDKで互換性をテストする 分離したサービス挙動にはユニットテストを使い、プロトコル処理、永続化、クライアントから見える状態には統合テストを使う。順序付きの統合実行を許容するのは、挙動が意図的に状態を持つ場合だけとする。 解析、応答形式、エラー、永続化の意味、URL生成、サービス有効化、代替プロトコル経路の変更には、自動テストが必要になる。 反復中は焦点を絞ったテストを実行し、その後、直接関係するテスト一式を実行する。実際のSDKの挙動へ影響し得る変更では、互換性検証プロジェクトを使う。生のHTTPよりSDKを使った検証を優先し、上流との意図的な相違は文書化する。 代替プロトコル経路が同じ操作を提供する場合は、意味が同等であることをテストする。状態を永続化する場合は、関係する各保存方式で読み込みとフラッシュの挙動を検証する。 手動要求だけから互換性を主張してはならない。挙動を変更したのに自動テストがない場合は、欠けているテストと追加できなかった理由を説明する。 ## 新しいサービスを最後まで仕上げ、リリースの動きはついでに変えない サービスを追加する場合は、コントローラー、サービス、モデルを作成し、登録、正本設定とテスト設定の追加、ファクトリー経由の保存領域接続、テスト追加、文書更新まで行う。 完了前に次を確認する。 - 関連テストとプロトコル互換性検査を実行する。 - 独自エンドポイントや便宜的な通信形式を導入していないことを確認する。 - 設定、保存領域、ライフサイクル、文書の更新を検証する。 - 生成されるURLとリソース識別子の一貫性を確認する。 - 頻繁に通る処理経路では、構造化ログを使い、不要なログを抑える。 プルリクエストは焦点を絞り、明示的な変更でない限り既存の挙動を保ち、無関係なリファクタリングを分離する。慣例に沿ったコミット種別を使い、作成者情報は人間だけにする。 リリースブランチ、タグ、配布ワークフローを重要基盤として扱う。開発ブランチへマージしただけでは、安定版のリリースを証明できない。サービス機能を実装する際に、付随的にリリース挙動を変えてはならない。