So I have a rails application that use jsonapi-resources gem and in global config specified this config
JSONAPI.configure do |config|
config.maximum_page_size = 1000
end
https://jsonapi-resources.com/v0.10/guide/basic_usage.html
But I want to use custom maximum_page_size in separate API resources for example /api/logs
module Api
class LogResource < ApplicationResource
immutable
model_name 'Api::Log'
primary_key :uuid
def self.default_sort
[{ field: 'time_start', direction: :desc }]
end
end
end
SO My question how to specify config only for this specific JSON API resource?
From what I can determine in the source code maximum_page_size
cannot be directly overridden at a resource level, so it appears the best way to handle this would be to implement a custom Paginator
.
For your given example I think something as simple as the following should work:
class LimitedPageSizePaginator < PagedPaginator
MAX_PAGE_SIZE = 100
def initialize(params)
super
verify_page_size_limit
end
private
def verify_page_size_limit
if @size > MAX_PAGE_SIZE
fail JSONAPI::Exceptions::InvalidPageValue.new(:size, @size,
detail: "size exceeds maximum page size of #{MAX_PAGE_SIZE}.")
end
end
end
Then you should be able to specify the Paginator
for your resource
module Api
class LogResource < ApplicationResource
immutable
model_name 'Api::Log'
primary_key :uuid
paginator :limited_page_size
def self.default_sort
[{ field: 'time_start', direction: :desc }]
end
end
end
If you need to make this more flexible e.g. not a fixed constant. Then we would need to create a method that dynamically creates a class on on the fly with the appropriate limitation set and then utilize that as the Paginator
, something like.
module PaginatorCreator
class LimitedPaginator < PagedPaginator
class << self
attr_accessor :limit
def paginator_name
self.name.demodulize.underscore[..-11].to_sym
end
end
def initialize(params)
super
verify_page_size_limit
end
private
def verify_page_size_limit
if @size > self.class.limit
fail JSONAPI::Exceptions::InvalidPageValue.new(:size, @size,
detail: "size exceeds maximum page size of #{self.class.limit}.")
end
end
end
def self.create_limited_paginator(resource:,limit:)
klass = Object.const_set("#{resource.name.demodulize}LimitedPaginator",Class.new(LimitedPaginator))
klass.limit = limit
resource.paginator(klass.paginator_name)
end
end
Then use as
class LogResource < ApplicationResource
PaginatorCreator.create_limited_paginator(resource: self, limit: 100)
end
Please Note: I have not used this library so there may be better solutions.