Trading API入門:GeteBayDetailsでメタデータを取得し、レガシーAPIの構造を攻略する

Trading API入門:GeteBayDetailsでメタデータを取得し、レガシーAPIの構造を攻略する

前回の記事はこちら

はじめに

本記事は、全42回にわたる「eBay API 実践ガイド」の第3回です。

前回までに認証(OAuth)と環境構築(Sandbox/Prod)の基盤が完成しました。今回からは、いよいよ実際のデータを eBay から取得します。

この記事で得られること:

  • なぜモダンな REST API ではなく、レガシーな Trading API (XML) を使う必要があるのかの理解。
  • Trading API 独自の HTTP ヘッダー(X-EBAY-API-IAF-TOKEN など)と XML リクエストの構築方法。
  • GeteBayDetails を用いて、出品に必須となる「配送メタデータ」を取得し、ローカルに JSON キャッシュとして保存する実装パターン。

背景・なぜこれが重要か (Motivation)

「eBay の開発を始めるなら、最新の Sell REST API だけで完結させたい」。誰もがそう思います。

しかし、現在でも 「出品(Listing)の詳細な制御」や「一部の高度なセラー設定」においては、依然として Trading API が主役 です。eBay のコアシステムは巨大であり、すべての機能が完全に REST に移行しきっているわけではありません。

そして、Trading API を扱う上で最初に立ちはだかる壁が 「ハードコードの罠」 です。

例えば、出品時に「USPS Priority Mail」を指定したい場合、単にその文字列を送るのではなく、eBay 内部で定義された正確な Enum 値を送る必要があります。これらの値は予告なく追加・廃止されるため、eBay から最新のメタデータを取得(GeteBayDetails)してマスタデータとして保持しておくこと が、堅牢なシステムを組むための第一歩となります。

基本的な使い方(ベースライン)

Trading API (エンドポイント: https://api.ebay.com/ws/api.dll) と REST API の最大の違いは以下の2点です。

  • ペイロードが JSON ではなく XML である。
  • OAuth トークンの渡し方が Authorization: Bearer ではなく、専用ヘッダー X-EBAY-API-IAF-TOKEN である。

必須の HTTP ヘッダー

Trading API を叩くためには、以下のヘッダーが必須です。

  • X-EBAY-API-CALL-NAME: 実行するメソッド名 (例: GeteBayDetails)
  • X-EBAY-API-SITEID: 対象とする eBay サイトの ID (US は 0、UK は 3、Japan は 201)
  • X-EBAY-API-COMPATIBILITY-LEVEL: 使用する API のバージョン(※最新値は eBay Developer Portal の Trading API Release Notes で確認できます)
  • X-EBAY-API-IAF-TOKEN: OAuth アクセストークン
  • Content-Type: text/xml

DetailNameCodeType:取得できるメタデータの種類

GeteBayDetails に渡せる DetailName(取得したい情報の種類)は、eBay が定義する DetailNameCodeType という Enum で管理されています。主なものを以下に示します。

DetailName 内容
ShippingServiceDetails 利用可能な配送方法と内部コード
ShippingCarrierDetails 配送業者と内部キャリアコード
ReturnPolicyDetails 返品ポリシーの選択肢
CountryDetails 国コード一覧
CurrencyDetails 通貨コード一覧
SiteDetails eBay サイト ID 一覧
TimeZoneDetails タイムゾーン一覧

本記事では、出品時に必ず必要となる ShippingServiceDetails(配送方法)と ShippingCarrierDetails(配送業者)の2つを取得します。

なぜ2つ必要か?

出品時の ShippingDetails には「どの業者(Carrier)の」「どのサービス(Service)を使うか」を別々のフィールドで指定する必要があります。例えば「USPS の Priority Mail」であれば、CarrierコードとServiceコードの両方が揃って初めて正しい出品データになります。

※その他のメタデータ(返品ポリシーなど)も同様の手法で取得可能です。より複雑な出品要件に応じたメタデータ設計が必要な場合は、連載の後半で触れるか、個別にご相談ください。

実務で躓く場面・深いポイント (Core)

GeteBayDetails を扱う上で初心者がよくやる失敗が、「パラメータを指定せずにリクエストを投げてしまうこと」 です。

何も指定しないと、すべてのメタデータを含む数MBにも及ぶ巨大な XML が返却され、パース処理でメモリを圧迫し、API のレスポンスタイムも劇的に悪化します。

実務では、必要な DetailName を明示的に指定して取得 し、Python の辞書(JSON)に変換して扱うのが鉄則です。また、XMLのパース時には要素が存在しない(None)ケースを考慮した堅牢なコードが求められます。

実装: 配送メタデータの取得と JSON キャッシュ化

第1回・第2回で作成したクラスをインポートし、配送業者と配送サービスのメタデータを安全に抽出するスクリプトを記述します。

# get_ebay_details.py import requests import xml.etree.ElementTree as ET import json from config import eBayConfig from ebay_token_manager import eBayTokenManager def fetch_ebay_details(config: eBayConfig, token: str, detail_names: list) -> dict: """
    GeteBayDetailsを実行し、指定されたメタデータを取得する
    """ # 1. Trading API 固有のヘッダー構築 headers = { "X-EBAY-API-CALL-NAME": "GeteBayDetails", "X-EBAY-API-SITEID": "0", # USサイト "X-EBAY-API-COMPATIBILITY-LEVEL": "1323", # 常にリリースノートで最新を確認 "X-EBAY-API-IAF-TOKEN": token, "Content-Type": "text/xml" } # 2. XML ペイロードの動的生成(必要な DetailName のみ指定) detail_name_tags = "".join([f"<DetailName>{name}</DetailName>" for name in detail_names])
    
    xml_payload = f"""<?xml version="1.0" encoding="utf-8"?>
    <GeteBayDetailsRequest xmlns="urn:ebay:apis:eBLBaseComponents">
        <ErrorLanguage>en_US</ErrorLanguage>
        <WarningLevel>High</WarningLevel>
        {detail_name_tags}
    </GeteBayDetailsRequest>
    """ # 3. リクエスト送信 response = requests.post(config.trading_api_url, headers=headers, data=xml_payload)
    response.raise_for_status() # 4. XMLのパースと名前空間(Namespace)の処理 # 深いポイント: eBayのXMLには xmlns が定義されているため、検索時に namespace 指定が必須 namespace = {'ns': 'urn:ebay:apis:eBLBaseComponents'}
    root = ET.fromstring(response.text) # APIエラーのチェック ack_node = root.find('ns:Ack', namespace)
    ack = ack_node.text if ack_node is not None else "" if ack not in ['Success', 'Warning']:
        errors_node = root.find('ns:Errors/ns:LongMessage', namespace)
        errors = errors_node.text if errors_node is not None else "Unknown API Error" raise Exception(f"API Error: {errors}") # 5. 必要なデータを抽出して dict に格納 result_data = { "ShippingServices": [], "ShippingCarriers": []
    } # ① 配送サービス (ShippingServiceDetails) の抽出 for shipping in root.findall('ns:ShippingServiceDetails', namespace):
        valid = shipping.find('ns:ValidForSellingFlow', namespace) # 本番稼働時のバグ防止: 要素が存在しない場合(None)のガードを必ず入れる if valid is not None and valid.text == 'true':
            service_node = shipping.find('ns:ShippingService', namespace)
            desc_node = shipping.find('ns:Description', namespace)
            
            result_data["ShippingServices"].append({ "Service": service_node.text if service_node is not None else "", "Description": desc_node.text if desc_node is not None else "" }) # ② 配送業者 (ShippingCarrierDetails) の抽出 for carrier in root.findall('ns:ShippingCarrierDetails', namespace):
        name_node = carrier.find('ns:ShippingCarrier', namespace)
        desc_node = carrier.find('ns:Description', namespace) if name_node is not None:
            result_data["ShippingCarriers"].append({ "CarrierCode": name_node.text, "Description": desc_node.text if desc_node is not None else "" }) return result_data if __name__ == "__main__": # 前回の基盤を利用してトークンと環境設定を解決 config = eBayConfig()
    manager = eBayTokenManager(config.client_id, config.client_secret, config.refresh_token, config.env) # 取得したいメタデータの種類を指定 target_details = ["ShippingServiceDetails", "ShippingCarrierDetails"] print(f"Fetching eBay Details from {config.env} environment...")
    details = fetch_ebay_details(config, manager.get_token(), target_details) # JSONファイルとしてローカルに保存(キャッシュ化) with open('ebay_shipping_metadata.json', 'w', encoding='utf-8') as f:
        json.dump(details, f, indent=2, ensure_ascii=False) print("Successfully saved metadata to ebay_shipping_metadata.json")

パフォーマンス・スケーリング視点 (深度)

この GeteBayDetails で取得できる「サイトメタデータ」は、頻繁に変更されるものではありません。

出品(Listing)処理を行うたびにこの API を叩く設計にしてしまうと、ネットワークのオーバーヘッドが発生し、eBay の Rate Limit(レート制限)を無駄に消費してしまいます。

【ベストプラクティス】
大規模なシステムでは、このデータを取得するバッチジョブ(Cron)を週に1回程度実行し、結果を Redis や RDB、あるいはローカルの JSON ファイルとしてキャッシュします。
出品ワーカーは API を叩くのではなく、「キャッシュされたローカルデータ」 を参照して、バリデーションや UI のセレクトボックス描画を行うアーキテクチャにすべきです。

まとめ

本記事では、eBay API のコアとも言える Trading API の基礎と、サイトメタデータの取得方法を解説しました。

  • ベースライン: REST とは異なるヘッダー (X-EBAY-API-IAF-TOKEN) と XML ペイロードの構造。
  • 深いポイント: DetailName を指定して巨大なレスポンスを回避する技術と、xml.etree を用いた Namespace 付き XML のパース処理。要素の欠落(None)に耐える堅牢な実装。
  • スケーリング: マスタデータとしてローカルに JSON キャッシュを持ち、出品ごとの無駄な API 呼び出しを避けるアーキテクチャ。

このメタデータ(配送方法や業者の正確な Enum 値)が手元にあることで、今後の出品 API 構築時のエラー率は劇的に下がります。

次のステップ

出品に必要なデータが揃い始めました。次回(#4)は、出品の実装に入る前のもう一つの重要な準備、「画像のアップロード (UploadSiteHostedPictures)」 です。

外部 URL の画像を直接 eBay に渡すのではなく、一度 eBay のサーバー(EPS)にホスティングさせることで、表示速度を最適化し、出品時の画像エラーを防ぐ実務的な手法を解説します。お楽しみに!

トップに戻る