スプラトゥーン3のステージ情報APIを作った
スプラトゥーン3のステージ情報API (Spla3 API) を作りました。
現時点では毎日9,000リクエストほどアクセスがあり、そこそこ使っていただけているようです。
この記事ではAPIのシステム構成について簡単に紹介します。
システム構成
Spla3 APIは全てAWSで動いており、次のコンポーネントを使用しています。
- CloudFront
- WAF
- S3
- Athena
- API Gateway
- Lambda (Golang)
- DynamoDB
全てのリクエストはCloudFrontとWAFを経由し、静的コンテンツはS3へ、APIリクエストはAPI Gatewayへルーティングされます。アクセスログはS3に保管され、Athenaで閲覧や検索が可能です。
Lambdaは以下の3つで役割が分かれています。
- Batch用Lambda
- 最新のステージ情報を取得してDynamoDBに入れる
- API用Lambda
- DynamoDBからステージ情報を取得してJSON形式でレスポンス
- Bot用Lambda
- DynamoDBのステージ情報を元に Twitter bot として定期ツイートする
Spla2 APIの反省点
スプラトゥーン2のときも同様のAPIを作ったものの、クラウド上のVMインスタンスで動かしているため維持コストの高さが課題でした。
そのため今回は常時稼働のインスタンスを廃止し、マネージドサービスのみで構築しています。
開発言語はGoに統一
Spla2 APIのときはPerlとGoが混在していましたが、Spla3 APIではGoに統一しました。
ステージ情報の取得部分やAPIレスポンス部分、Twitter botも全てLambda上のGoで動いています。
余談ですが、GoからDynamoDBを操作する際は公式のヘルパーパッケージ expression
を活用するとクエリが書きやすくて便利でした。
DynamoDBのテーブル設計
現時点でスプラトゥーン3には5つのゲームモードがあり、それぞれステージ情報が異なります。
- レギュラーマッチ
- バンカラマッチ (チャレンジ)
- バンカラマッチ (オープン)
- フェスマッチ ※イベント開催時のみ
- サーモンラン
例としてレギュラーマッチの現在のステージを取得すると、以下のようなレスポンスを得られます。
% curl -s https://spla3.yuu26.com/api/regular/now | jq .
{
"results": [
{
"start_time": "2022-10-28T01:00:00+09:00",
"end_time": "2022-10-28T03:00:00+09:00",
"rule": {
"key": "TURF_WAR",
"name": "ナワバリバトル"
},
"stages": [
{
"id": 10,
"name": "マサバ海峡大橋",
"image": "https://xxxxxxxx"
},
{
"id": 15,
"name": "ザトウマーケット",
"image": "https://xxxxxxxx"
}
],
"is_fest": false
}
]
}
詳細は APIドキュメント を参照していただきたいですが、ゲームモードと時間帯を指定してレスポンスを得る仕様のため、DynamoDBテーブルは以下の設計としました。
Partition key | Sort key | Attribute |
---|---|---|
GameMode | StartTime | <ステージ情報等> |
Partition keyでゲームモードを指定、Sort keyで任意の時間を指定することで、欲しいステージ情報を特定できます。今後Xマッチなど新たなゲームモードの追加が予告されているため、それを見越した汎用的な構成としました。
負荷耐性とランニングコスト
全てのコンポーネントが自動でスケールアウトするため、負荷耐性は非常に高いです。
10,000req/min のアクセスでも問題なく捌けることを確認しました。
ただし捌けてしまうことで想定外の費用が発生する可能性もあり、大量アクセスを防ぐWAFとコストアラートで対策をしています。
費用としてはWAF以外ほぼ無料枠に収まっており、月額7ドルほどです。
AWSのクレジットが80ドル分ほど余っているため請求自体は発生していません。
まとめ
- スプラトゥーン3のステージ情報APIを作りました
- マネージドサービスをフル活用することで負荷耐性と低コストを両立できました
- スプラトゥーン3関連で何か作りたいときに活用してみてね