【要約】GMOコインFX APIでHTTP 200なのに約定が0件になった話 — ボディのstatusを見ない罠 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者が、GMOコインFX APIを用いた自動売買システムにおいて、約定取得APIのレスポンス処理を誤った実装で行ったことで、データの不整合が発生した。具体的には以下の問題に直面した。
- ・GMOコインFX APIは、業務エラー時もHTTP 200を返す仕様である。
- ・httpx.Response.raise_for_status() では、業務エラーを検知できない。
- ・エラー時のレスポンスにはdataフィールドが存在しない。
- ・パース時に空配列として処理され、エラーが「約定なし」に化けた。
- ・実際には約定があったにもかかわらず、日次ノートに「約定0件」と誤った情報が記録された。
// Approach
開発者は、HTTP層の検査とは別に、レスポンスボディ内のstatusフィールドを厳格に検証する仕組みを導入した。以下のステップで解決を図った。
- ・raise_for_gmo_status関数を実装し、statusが0以外の場合にGmoApiErrorを投出する。
- ・約定取得(GET)メソッド内で、HTTP検査の直後に当該関数を呼び出す。
- ・参照系APIに対しては、同一実行内での短期間リトライを実装した。
- ・取得に失敗した場合は、誤ったレポートを生成しないよう、処理自体を失敗側に倒す設計とした。
// Result
この対策により、APIの業務エラーを正確に検知できるようになり、データの整合性が確保された。具体的な成果は以下の通りである。
- ・業務エラー発生時にGmoApiErrorが発生し、空配列への「化け」が解消された。
- ・回帰テストにより、HTTP 200の業務エラーを正しく例外として扱うことを保証した。
- ・「取得失敗」と「約定なし」が明確に区別され、日次レポートの信頼性が向上した。
Senior Engineer Insight
> 外部APIの設計を過信せず、「通信成功 ≠ 業務成功」という前提で防御的プログラミングを行うべきだ。特に金融系のようにデータの整合性が生命線となる現場では、HTTP層とアプリケーション層の二段構えのバリデーションは必須である。本件のように、一部の経路(参照系)だけ検査が漏れる「実装のムラ」が致命的な誤報を招く。共通のバリデーション関数を強制的に適用する設計や、静的解析によるチェックを検討すべきだ。