Steam WebAPIとVue.jsを利用してSteam公式では出来ないレビュースコア検索や販売日検索の結果を表示する『Steamの殿堂』を作るまでの過程

# はじめに
今回「Steam WebAPI」と「Vue.js」を用いて**Steamゲーム検索サイト(Steamの殿堂)**を作成しました。そのときのノウハウや技術を公開したいと思います(エンジニアはアウトプットすると良いってばっちゃが言ってた)。

このSteamゲーム検索サイトを作った動機ですが、私が拝見してるこのサイトの補完サイトである『Qiitaの殿堂』がとても便利で、「Steamでも同じようなサイトを作ってみたい！」っと思ったのが動機になります(名前が似ているのはリスペクトからです。~~決してパク~~)。

# どのようなサイトか
Steam公式では出来ないレビュースコア検索や販売日検索の結果をランキング形式で表示するサイト。
　⇒ 『[Steamの殿堂](https://steamasiato.com/html/pantheon.html)』
![test2-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/87606178-4440-4f6e-786c-6c270965d84d.gif)

# お礼
『Steamの殿堂』の作る動機を与えてくださった『Qiitaの殿堂』の管理者様、ありがとうございます。
　⇒ 『[Qiitaの殿堂](http://youwht.ml/)』

『Steamの殿堂』の作るにあたって大変参考になるノウハウを公開して頂いた「itito」様、ありがとうございます。
　⇒ 『[Steamに登録されている大量のゲームから埋もれている名作を見つけ出す](https://qiita.com/itito/items/e1c47d812c8a1cb5437b)』

##1. Steam WebAPIで情報を取得
###1.1.
Steam WebAPI の`GetAppList`を実行して、Steamに登録されている全ての**ゲームID**と**ゲーム名**をJSON形式で取得します。

~~~html:URL
https://api.steampowered.com/ISteamApps/GetAppList/v2/
~~~

~~~yml:実行結果
{
  applist: {
    apps: [
      {
        appid: 216938,
        name: "Pieterw test app76 ( 216938 )"
      },
      {
        appid: 660010,
        name: "test2"
      },
      ######### 略 #########
      {
        appid: 1251950,
        name: "Escape of Mari: The Polar Ladybug"
      }
    ]
  }
}
~~~

###1.2.
Steam WebAPI の`appreviews`の引数{appid}を設定して実行し、{appid}に設定したゲームIDのレビュー情報をJSON形式で取得します。このWebAPIを**「1.1.」で取得したゲームIDの数だけ実行します（2020年02月16日時点で90346個）。**

~~~html:URL
https://store.steampowered.com/appreviews/{appid}?json=1&start_offset=0&language=all&purchase_type=all&num_per_page=0
~~~

~~~yml:実行結果
{
  success: 1,
  query_summary: {
    num_reviews: 0,       # 応答に返されたレビューの数(今回は利用しない)
    review_score: 9,      # レビュースコア(例えば、'4'は'ほぼ不評'、'9'は'圧倒的に好評')
    review_score_desc: "Overwhelmingly Positive", # レビュースコアの説明
    total_positive: 2459, # 好評なレビューの総数
    total_negative: 30,   # 不評なレビューの総数
    total_reviews: 2489   # レビューの総数
  }
}
~~~

デフォルトだと取得するレビュー情報に制限が掛かるため、`language=all`と`purchase_type=all`のオプションを設定する必要があります。そうすることで、以下のレビュー情報ではなく
![011-001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/a8117932-009e-2608-3a5c-2cea3d13e795.jpeg)
以下のレビュー情報を取得することに成功しました。
![011-002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/b9040314-395b-dfb2-ba28-0025da4ae2ca.jpeg)
もちろん、1つ1つ実行するのは現実的ではないので**node.js**を利用して独自関数を作成し、自動で実行した結果をファイルに出力するようにしました。

###1.3.
Steam WebAPI の`appdetails`の引数{appid}を設定した後に実行して、{appid}に設定したゲームIDの詳細情報をJSON形式で取得します。

~~~html:URL
https://store.steampowered.com/api/appdetails?appids={appid}
~~~

~~~yml:実行結果
{
  "success": true,
  "data": {           # ゲームデータ
    "type": "game",   # 他には'dlc'、'demo'、'advertising'、'mod'、'video'
    "name": "Epic Battle Fantasy 5",
    "steam_appid": 454550,
    "is_free": false, # 無料の場合は'true'、無料でない場合は'false'
    "genres": [       # ジャンル
      {
        "id": 2,
        "description": "ストラテジー"
      },
      ...
      {
        "id": 25,
        "description": "アドベンチャー"
      }
    ]
    "release_date": { # 販売日
      "coming_soon": false,
      "date": "2018年12月1日"
    }
}
~~~

ただ、ジャンルの情報の取得はできましたが、タグの取得ができませんでした...。
ジャンル情報は以下の情報で、
![011-003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/94554a33-1e66-e0a4-048a-5f7a67f0e56f.jpeg)
タグ情報は以下の情報です。
![011-004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/8311e23d-60f5-da6c-1159-e3341b34f189.jpeg)
Steamのカテゴリーは種類が少なく、
タグの方が種類が豊富でよりユーザに探しやすい情報なのでタグの情報がほしかったです...。
申し訳ございませんがタグを取得できるAPIを見つかるまではカテゴリーの情報を使用します。

##2. レビュー情報の登録と整形
###2.1.
「1.2」で出力したファイルをDBに格納します。DBは**MySQL**を利用しました。カラムは以下のように設定し、「1.2.」と「1.3.」で出力した情報を格納します。
※ タグは現時点では使用しないが、今後のために作っています。
![011-005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/85be7015-127c-da98-6a85-0d3c950ce377.jpeg)

###2.2.
「2.1.」の情報をCSVファイルに出力し、**node.js**を利用してcsv→jsonに変換する独自関数を作成し、JSON形式のファイルを出力するようにしました。

##3. Vue.jsでレビュー情報を画面へ出力
###3.1.
Webサイトを作ったことのない方に向けてですが、どのようにWebサイトを作るか"家"で例えて簡単に説明しますと、
 1. HTML5を使って、家の枠を組み立てる。
 2. CSS3を使って、家をカラフルにデザインする。
 3. JavaScriptを使って、家に電気やガスやエアコンなどの機能を加える。
上記3つのことを考えながらWebサイトを作っていきます。
最近はWordPressやBootstrapなど便利なサービスがありますが、今回は1から作りました。皆さんがWebサイトを作るときは、そのサービスを利用することをオススメします(1から作るのは色々と大変)。

###3.2.
HTML5を組み立てていきます。今回は**Vue.js**を利用するため、独自の構文を取り入れながら将来機能を追加しやすいように組み込んでいきます。完成したHTML5のソースは以下画像のようになりました。
![011-006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115232/56786a57-3ac6-943a-27e8-c6f2ac93d2c4.jpeg)
上部がHTMLのFORMタグを使って検索する部分を組み立てて、下部がHTMLのTABLEタグを使って一覧表示する部分を組み立てました。今回は**Vue.js**を利用したので、`v-for`や`{{ }}`などの構文を必要なところに散りばめます。

###3.3.
CSS3を組み立てていきます。画像を出そうと思いましたが200行以上のソースコードがあって長くなるため、大変申し訳ございませんが割愛させて頂きます･･･

###3.4.
JavaScriptを組み立てていきます。Vueのインスタンスを生成する必要があるので、以下のように定義します。

~~~js:js
var list = new Vue({
  el: '要素',
  data: '情報',
  methods: {
    xxxx: function() {
      '関数処理の記載'
    }
  },
  computed: {
    yyyy: function() {
      '関数処理の記載'
    }
  }  
});
~~~

ここで重要なのが`el`、`data`、`methods`、`computed`の4つです。
`el`はこのVue定義がHTMLのどこの要素で使用するか設定します。
`data`は出力する情報を設定します。ここでは「2.3.」の情報を設定します。
`methods`と`computed`で検索処理とソート処理を実装します。

###3.5.
「3.2.」「3.3.」「3.4」を実装 → 実行 → 修正 → 実装 → ... と繰り返しながら、小さい機能単位でソースコードを構築していきます。私の持論ですが、一気にソースコードを実装するより細かく実装することで、バグの発見がしやすく修正もやりやすいので小さく組み立てていくのがいいと思います。

##4. サーバにアップロード
###4.1.
「2.」と「3.」で作ったものをサーバにアップロードします。
最後にサーバ上で動作確認をして、不具合がないことを確認して終了です。

# さいごに
以上が「Steam WebAPI」で情報を取得してから、「Vue.js」を利用した画面の表示するまでの実装過程です。一番大変だったのはnode.jsで独自関数を作って、Steam WebAPIを実行して情報を取得するところでした。Steam WebAPIは他にもたくさんの種類があるため、何かアイディアが思いついたらまた作ってみようと思います。