AWS の API はなぜ XML を返すのか - Query API から REST JSON への進化の歴史
S3 や EC2 の API が XML レスポンスを返す歴史的経緯、Query API と REST API の違い、Signature V2 から V4 への認証方式の進化、SDK が隠蔽している複雑さを解説します。
2006 年の API 設計 - XML が当然だった時代
S3 と EC2 が 2006 年にローンチされた当時、Web API の世界では XML が標準的なデータ形式でした。SOAP (Simple Object Access Protocol) が企業向け Web サービスの主流であり、XML Schema による厳密な型定義と WSDL (Web Services Description Language) によるサービス記述が「正しい」API 設計とされていました。JSON は 2001 年に Douglas Crockford が提唱していましたが、2006 年時点ではまだ広く普及しておらず、「軽量だが型安全性に欠ける」という評価でした。AWS の初期 API は、この時代の設計思想を反映しています。EC2 の API は「Query API」と呼ばれる形式で、HTTP GET リクエストのクエリパラメータにアクション名とパラメータを指定し、XML でレスポンスを受け取ります。たとえば、EC2 インスタンスの一覧を取得するリクエストは https://ec2.amazonaws.com/?Action=DescribeInstances&Version=2016-11-15 のような形式です。S3 の API は REST スタイルで、HTTP メソッド (GET、PUT、DELETE) とパスでリソースを操作しますが、レスポンスは XML です。
後方互換性の呪い - なぜ XML を廃止できないのか
AWS の最も重要な設計原則の一つが「一度公開した API を廃止しない」です。EC2 の Query API は 2006 年から 20 年近く動作し続けており、XML レスポンスの形式も変わっていません。数百万の顧客のアプリケーションがこの API に依存しているため、レスポンス形式を JSON に変更することは、大規模な破壊的変更になります。AWS はこの問題を、新しいサービスでは JSON を採用し、古いサービスの API はそのまま維持するというアプローチで解決しています。2012 年以降にローンチされたサービス (DynamoDB、Lambda、API Gateway など) は、ほぼすべて JSON ベースの REST API を採用しています。DynamoDB の API は JSON リクエスト/レスポンスで、Content-Type は application/x-amz-json-1.0 です。Lambda の API も JSON ベースです。一方、EC2、S3、SQS、SNS などの初期サービスは、今でも XML レスポンスを返します。AWS SDK はこの違いを内部で吸収しており、開発者は SDK を使う限り XML と JSON の違いを意識する必要はありません。
Signature V4 - すべてのリクエストに署名する仕組み
AWS API のもう一つの特徴は、すべてのリクエストに暗号学的な署名が必要なことです。現在の標準である Signature Version 4 (SigV4) は、リクエストの HTTP メソッド、URL、ヘッダー、ボディを連結してハッシュ化し、シークレットアクセスキーで HMAC-SHA256 署名を生成します。この署名は Authorization ヘッダーに含められ、AWS 側で検証されます。SigV4 の署名プロセスは 4 ステップで構成されます。第 1 に、正規リクエスト (Canonical Request) の作成。HTTP メソッド、URI、クエリ文字列、ヘッダーを正規化した文字列を作成します。第 2 に、署名対象文字列 (String to Sign) の作成。日付、リージョン、サービス名、正規リクエストのハッシュを連結します。第 3 に、署名キーの導出。シークレットアクセスキーから、日付、リージョン、サービスごとの署名キーを段階的に導出します。第 4 に、署名の計算。署名キーで署名対象文字列を HMAC-SHA256 署名します。この複雑なプロセスを手動で実装するのは現実的ではなく、AWS SDK が内部で自動的に処理しています。SDK を使わずに curl で AWS API を呼び出す場合、この署名プロセスを自前で実装する必要があり、デバッグが極めて困難です。
SDK が隠蔽している複雑さ
AWS SDK は、API の複雑さを開発者から隠蔽する巨大な抽象化レイヤーです。SDK が内部で処理していることは多岐にわたります。リクエストの署名 (SigV4)、XML/JSON のシリアライズ・デシリアライズ、リトライロジック (指数バックオフ付き)、エラーハンドリング (一時的なエラーと永続的なエラーの区別)、ページネーション (大量の結果を自動的に複数リクエストで取得)、リージョンエンドポイントの解決、一時的な認証情報の自動更新 (IAM ロールの AssumeRole) などです。SDK v3 (JavaScript) や boto3 (Python) は、これらの処理をミドルウェアパイプラインとして実装しており、開発者がカスタムミドルウェアを追加することも可能です。SDK のリトライロジックは特に重要です。AWS の API はスロットリング (レート制限) を適用しており、短時間に大量のリクエストを送信すると 429 (Too Many Requests) エラーが返されます。SDK は自動的に指数バックオフ (1 秒、2 秒、4 秒...) でリトライし、開発者がリトライロジックを実装する必要はありません。
API の進化と今後の方向性
AWS の API 設計は、20 年間で大きく進化しました。初期の Query API + XML から、REST + JSON へ、そして最近では GraphQL (AppSync) やイベント駆動 (EventBridge) へと、API のパラダイム自体が多様化しています。AWS の API 設計で一貫しているのは、「API は一度公開したら変えない」という原則です。EC2 の API バージョン 2006-10-01 は今でも動作します。新しい機能は新しい API バージョンとして追加され、古いバージョンは廃止されません。この後方互換性の維持は、AWS の信頼性の根幹です。企業が数年かけて構築したシステムが、API の変更で突然動かなくなることはありません。一方で、この原則は技術的負債も生みます。20 年前の設計判断 (XML レスポンス、Query API 形式) が今でも維持されているため、新しい開発者にとっては「なぜこんな古い形式なのか」という疑問が生じます。その答えは「後方互換性のため」であり、これは AWS が顧客の信頼を最優先する姿勢の表れです。API 設計の歴史と原則を体系的に学ぶには、専門書籍 (Amazon)が参考になります。