如何缓存一个rails api控制器?

问题描述 投票:0回答:1

我在我的应用程序中看到了一些性能问题,我想知道我的缓存是否正常工作,或者我是否误解了错误的配置。我使用的是 快捷的jsonapi 用于序列化,它自带一个内置的缓存选项。

比方说

class BooksController < ApplicationController
...
  def index
    @books = Books.includes(:author, :publisher).with_attached_cover.all
    BookSerializer.new(@book, { include: [:author, :publisher]}).serializable_hash.to_json
  end
...
end

class BookSerializer
  include FastJsonapi::ObjectSerializer
  cache_options store: Rails.cache, namespace: 'fast-jsonapi', expires_in: 24.hours

  belongs_to :author
  belongs_to :publisher

  attributes :all_the_book_attributes_im_too_lazy_to_list
end

也让我们假设我有大约5000本书,2000个作者和100个出版商,所以我希望缓存能在性能上有很大的不同。

然而,事实上,我看到我的数据库在启用或不启用缓存的情况下都会出现同样的问题,而且响应时间非常慢。此外,当检查我的缓存时,它似乎只缓存了每一本单独的书,而不是作为一个整体的序列化哈希。

现在我想知道我是否完全错过了序列化器中缓存的目的,或者我是否需要在我的控制器中添加一些额外的层?如果是的话,有什么办法可以用DRY的方式来实现吗?会不会和序列器的缓存冲突?那序列化器中的缓存到底有什么作用呢?

我知道有多种方式的cache可以使用。我只是不知道该组合哪些,是否要防止这些层之间的冲突。

ruby-on-rails caching serialization rails-api fastjsonapi
1个回答
0
投票

就像我可以看到你想缓存这个JSON响应。

为这个查询添加一个缓存键。你需要这个来使响应无效,当书籍随着时间的推移而改变。

# model book.rb
class Book < ApplicationRecord
...
  def self.cache_key
    {
      serializer: 'books',
      stat_record: Book.maximum(:updated_at)
    }
  end
...
end

在你的控制器中,使用该键从缓存中获取数据,或者做一个新的查询。

class BooksController < ApplicationController
...
  def index
    @books = Rails.cache.fetch(Book.cache_key) do
      BookSerializer.new(
        Books.includes(:author, :publisher).with_attached_cover.all, 
        { 
          include: [:author, :publisher]
        }
      ).serializable_hash.to_json
    end

    render json: @books 
  end
...
end

你也可以看看页面缓存。

另外,如果你有5000个条目,你应该考虑分页。

© www.soinside.com 2019 - 2024. All rights reserved.