概要
自分もそうですが個人開発でAPIを使う方も多いと思います。
ただ実装過程で外部APIを頻繁に呼び出すことは、リAPIの利用制限、コストの増加を招きます。
これを解決するための方法としてキャッシュ
です。
そんな時にRailsのキャッシュ
というものを使えばこの問題を解決できます。
Railsガイド Rails のキャッシュ機構
私は初学者のため、間違った情報があればコメントなどで教えていただけると幸いです。
キャッシュとは
「キャッシュ(caching)」
とは、リクエスト・レスポンスのサイクルの中で生成されたコンテンツを保存しておき、次回同じようなリクエストが発生したときのレスポンスでそのコンテンツを再利用することを指します。
多くの場合、キャッシュ
はアプリケーションのパフォーマンスを効果的に増大するのに最適な方法です。キャッシュを導入することで、単一サーバーや単一データベースのWebサイトでも、数千ユーザーの同時接続による負荷に耐えられるようになります。
とRailsガイドに書かれています。
つまり、キャッシュ
を使って一回APIを叩けばそのデータやコンテンツが保存され、再度叩いてもその保存されたデータやコンテンツを再利用できるからリクエストやコストがかからないということらしいです。
実装
今回はレシピなどが取得できるSpoonacular API
を使って実装してみます。
状況によって多少コードは変わると思いますが、GPTに聞けばわかると思います笑
1. 開発環境でのキャッシュ有効化
開発環境でキャッシュを有効にするためにターミナルで次のコマンドを実行します。
$ bin/rails dev:cache
2.条件付きGETの利用
以下のコードは、対象のリソースを提供するコントローラのアクションに追加します。
indexアクションでのキャッシュ
ユーザーごとに異なる結果が返される可能性があるため、キャッシュのキーにはユーザーのIDなどの一意の情報を含めます。
def index
user = current_user || User.new(name: "Guest")
cache_key = "meal_plan_for_user_#{user.id || 'guest'}"
@meal_plan = Rails.cache.fetch(cache_key, expires_in: 1.hour) do
SpoonacularService.generate_meal_plan
end
end
showアクションでのキャッシュ
エンドポイントがクライアントのキャッシュに存在するリソースの最新版を持っているかどうかを確認するために、stale?
を使います。
例)recipes_controller.rb
def show
@resource = YourModel.find(params[:id])
if stale?(last_modified: @resource.updated_at.utc, etag: @resource.cache_key_with_version)
render json: @resource
end
end
これにより、同じユーザーの同じリクエストや同じレシピの情報取得リクエストが1時間以内に行われた場合、SpoonacularServiceを介してのAPIの呼び出しは行われず、キャッシュから情報が返されるようになります。これでAPIのリクエスト回数やコストを削減できます。
最後にサーバーを再起動します