EVE Online Swagger Interface(ESI)を使う①

EVE ESIとは

CCP GamesのEVE Onlineには、ユーザーがアクセスしてゲームデータを取得・変更でき、サードパーティソフトウェアに利用できるAPIがあります。

www.eveonline.com

このAPIは、正式名称のEVE Online Swagger Interfaceを略して、ESIと呼ばれます。

クラウドの勉強がてら、ESIを使ったWebアプリでも作ろうかと思ったのでメモしておきます。

とりあえず今回は認証などが不要なAPIを使ってみます。

ESIの概要

ESIで提供されているAPIは、公式サイトで確認できます。

ESI仕様ページではLegacy、Latest、Devの3バージョンが記載されています。この記事では原則Latestを参照します。

ESI API一覧

各カテゴリを選択すると、詳細が確認できます。右側に錠前のマークがついているAPIは認証が必要です。

IDの取り扱い

大抵のシステムがそうであるように、EVEではあらゆる存在に一意なIDが割り当てられています。IDの割り当て範囲はドキュメントで確認できます。

IDが既知であればそれを用いて情報を要求できますが、未知の場合はまずIDを確認しなければなりません。

IDの確認には/universe/ids/エンドポイントを利用します。

ID参照に用いるAPI

詳細画面でTry it out を選ぶと結果をAPIを試したり、Curlコマンドを生成できたりします。

ドキュメントでお試しした画面

注意点として、/universe/ids/は完全一致のみ参照します。例えばDominixとDominix Navy Issueは同時検索できません。以前は部分一致で検索できるAPIがあったのですが、いつの間にか消えました。ユーザー名はともかくアイテム名は利用者側で名称とIDの一覧を保持しておけということかもしれません。

例えばDonimixとHyperionのIDを調べるプログラムをPythonで実装するとこんな感じになると思います。

注意ですがlanguageと問い合わせIDの言語は一致させる必要があります。language=enでドミニックスをPOSTしたりlanguage=jaでDominixをPOSTしても結果無しと帰ってきます。

import requests

url = "https://esi.evetech.net/latest/universe/ids/?datasource=tranquility&language=en" 
payload = "[  \"Dominix\",  \"Hyperion\"]"
response = requests.post(url, data=payload)

print(response.status_code)
print(response.headers)
print(response.text)

実行結果

200
{'Date': 'Tue, 05 Sep 2023 13:11:26 GMT', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '165', 'Connection': 'keep-alive', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Headers': 'Content-Type,Authorization,If-None-Match,X-User-Agent', 'Access-Control-Allow-Methods': 'POST,OPTIONS', 'Access-Control-Allow-Origin': '*', 'Access-Control-Expose-Headers': 'Content-Type,Warning,ETag,X-Pages,X-ESI-Error-Limit-Remain,X-ESI-Error-Limit-Reset', 'Access-Control-Max-Age': '600', 'Allow': 'OPTIONS,POST', 'Content-Language': 'en', 'Strict-Transport-Security': 'max-age=31536000', 'Vary': 'Accept-Language', 'X-Esi-Error-Limit-Remain': '100', 'X-Esi-Error-Limit-Reset': '34', 'X-Esi-Request-Id': '853ae06e-9b59-46f6-bace-e4396001bfab'}
{"characters":[{"id":1093289919,"name":"Dominix"},{"id":144930206,"name":"Hyperion"}],"inventory_types":[{"id":645,"name":"Dominix"},{"id":24690,"name":"Hyperion"}]}

色々ヘッダーが付いていますが、本文は最後の行です。これらの名称はcharactersにも使用可能なので二つのカテゴリにまたがって結果が返ってきています。

Headerについて

いくつかESIに特有のヘッダーがあるので説明します。

まず前提として、ESIにはレート制限がありません(メール関連など一部を除く)。その代わりに、Error Rate Limitingというシステムがあります。

このシステムでは一定時間の枠内に一定回数以上の4XXおよび5XXエラーが発生すると残りの枠内では420エラーが返されます。このシステムによって間違ったリクエストを大量に処理したり5XXエラーが発生するほど過剰な量のリクエストが送られることを防いでいます。

このError Rate Limitingに関わるヘッダーがx-esi-error-limit-remainx-esi-error-limit-resetです。

x-esi-error-limit-remainが0になるとAPIの利用が制限され、x-esi-error-limit-resetの時間(秒)が経過すると利用制限とx-esi-error-limit-remainの値がリセットされます。

つまり、x-esi-error-limit-remainが減るようであればAPIの使い方が正しいかを確かめたりアクセスが過剰になってないかを確認することが求められます。ちなみにこれを書いた時点では60秒で100エラーが制限のようでした。

このresponseのヘッダーにはありませんが、公式ドキュメントには他にexpireslast-modifiedヘッダーの存在も記載されています。

これは要求したデータがESIサーバーでキャッシュされている場合に使われ、expiresが次に新しいデータが取得されるまでの時間、last-modifiedがデータの取得タイミングです。

error-limitやexpiresで許容されているからといって不必要な規模や回数のリクエストはやめましょう。ESIは運営のリソースを浪費させないよう丁寧に使いましょう。規模が過剰の場合BANの可能性もあります。また、ESIはEVE本体と異なりストラクチャ探しなどの悪用目的での使用は禁止されています。今回は省略しましたが、ソフトウェアに組み込む際にはUserAgentに連絡先などを記載しましょう

とりあえずここまでまとめておきます。

その他のAPIの機能は実際に公式のページで確認してみてください。

何か指摘等あればコメントください

次回があれば認証が必要なAPIを触ってみます。

参考文献

ESI Documentation | esi-docs

EVE Swagger Interface