rakeファイルを用いる以外でwebAPIのリクエストを定期実行する方法について
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 390
こちらのAPIを用いてアプリを作っています。
https://www.football-data.org/documentation/quickstart
課金額には応じるのですが、基本的にヨーロッパのサッカーのクラブに所属している選手のデータであったり、最新の試合結果を返してくれるAPIです。単純ですが、この返ってきた値をテーブル上にして表示するというアプリケーションを(APIを使用する練習も兼ねて)作っているのですが問題があります。
その問題なのですが、リクエストを送るURIが多すぎることで、単純にURIが考えただけでも100、200個ほどあります。
つまり世界には様々なサッカーのクラブがあり、5ヶ国のリーグだったら単純に1リーグ20クラブ×5リーグで100クラブ分のエンドポイントがある訳です。
勿論ベースエンドポイントURIは同じなのですが、後に続くパスがクラブによって異なるのです。
最初はなるべく記述量が少なくなるよう1つのコントローラーでviewを表示できるようにするというルーティングをしており (参考):Controllerを作らずにViewを表示したい
view側で直接APIへリクエストするruby文を埋め込んでおりました。
html.erbテンプレートファイルでリクエストをし、帰って来たjson(ハッシュ)データを配列にして返しmapメソッド等を用い整形し、foreach文でテーブルに表示ということを行なっていました。
ですがこのteratailでそのような設計はまずいとの指摘を受け、task等に記述し、定期的にリクエストを送る処理を実行させるべきとのアドバイスも頂きました。確かにこのwebAPIもリクエスト制限(1分間に10リクエスト)があるため、ページを表示するたびにリクエストを送ることになってしまう為、納得でした。
しかしtask、rakeファイルでAPIへのリクエストを行なった場合viewでその値を表示するには、一度DBに保存させてコントローラを用いて必要な値を持ってこなければいけないということです。
そうなると、問題なのがテーブルを大量に作らなければならないということです。個人的にrails g model
を行いマイグレーションファイルを100-200回も作成するのは流石にしんどいのではと感じました。
そこで考えたのがDBに保存せず、そのAPIへリクエストするスクリプトを定期実行させることです。そうすれば逐一DBに保存、削除等を行わなくてもレスポンスの値そのままを定期的viewに反映できると思った為です。方法はまだ検索中なのでまだ分からないのですが、、、
改めて現在の問題を箇条書きで書くと
- APIにリクエストを送り返って来たハッシュデータを整形して表示したい
- リクエストを送るURIは100-200くらいある
- 1URIにつき表示のための1テンプレートなのでテンプレートも数100-200ある
- しかしviewにリクエスト文をベタ書きするのは設計上まずい
- rakeファイルを用いて定期的にリクエストを送り値をDBに保存しコントローラー側渡し表示すべき
- しかしマイグレーションファイルやテーブルをその分、generateするのは本末転倒な気もする
です
長くなってしまいましたが、要すると複数のAPIリクエストとレスポンスを受け取るスクリプトをwheneverのようなライブラリを用いて定期実行させ、且つDBを介さずviewに表示する方法はないのかということです。
もしくはDBを使用しても、少ないテーブル数で表示する方法があるのかということです。知識が足りなすぎて不甲斐ないですが宜しくお願い致します。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
モデルを100-200作る必要はありません。
作る必要のあるモデルは
- リーグデータ
- クラブデータ
- 選手データ
- 試合結果
でしょう
あとは、なんらかのバックグラウンドジョブによってこれらを更新・もしくは貯蓄して行きます
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/08/06 05:09 編集
もし良ければもう少し具体的に教えて欲しいのですが。例えば選手データというモデルとテーブルも一つだけ作ってそこに全部(リクエストしたURIの数だけ)のデータを詰めていくということでしょうか?
個人的に、club1という名前のサッカークラブがあったら選手のデータ(名前、国籍、ポジションなど)を突っ込むclub1_playersというテーブルに対しClub1_playerというモデルが存在するといった形でクラブ数分モデルとテーブルを用意しなければならないと思っていたのですが、、、何かもう少し効率の良いDBの設計方法があるということなのでしょうか?
正直、クラブのidとそのクラブに所属している選手データのうまいリレーション方法が思いつかなかったです。。。
2018/08/06 05:54
アソシエーションについて学ぶのがよいと思います。
参考までにおそらく
リーグ has_many クラブ
リーグ has_many 試合結果
クラブ belongs_to リーグ
クラブ has_many 選手
クラブ has_many ホームでの試合
クラブ has_many アウェイでの試合
選手 belongs_to クラブ
試合結果 belongs_to リーグ
試合結果 belongs_to ホームのチーム
試合結果 belongs_to アウェイのチーム
2018/08/06 06:03
実装イメージが湧いて来ました!