class Fbe::Middleware::RateLimit
- License
- MIT
Copyright - Copyright © 2024-2025 Zerocracy
Author -
Yegor Bugayenko (yegor256@gmail.com)
end
f.use Fbe::Middleware::RateLimit
connection = Faraday.new do |f|
@example Usage in Faraday middleware stack
by allowing the request to pass through to the GitHub API.
it for each API call. Every 100 requests, it refreshes the cached data
the results locally. It tracks the remaining requests count and decrements
This middleware intercepts calls to the /rate_limit endpoint and caches
Faraday middleware that caches GitHub API rate limit information.
- Copyright © 2024-2025 Zerocracy
- MIT
def call(env)
-
(Faraday::Response)
- The response from cache or the next middleware
Parameters:
-
env
(Faraday::Env
) -- The request environment
def call(env) if env.url.path == '/rate_limit' handle_rate_limit_request(env) else track_request @app.call(env) end end
def extract_remaining_count(response)
-
(Integer)
- The remaining requests count
Parameters:
-
response
(Faraday::Response
) -- The API response
def extract_remaining_count(response) body = response.body if body.is_a?(String) begin body = JSON.parse(body) rescue JSON::ParserError return 0 end end return 0 unless body.is_a?(Hash) body.dig('rate', 'remaining') || 0 end
def handle_rate_limit_request(env)
-
(Faraday::Response)
- Cached or fresh response
Parameters:
-
env
(Faraday::Env
) -- The request environment
def handle_rate_limit_request(env) if @cached_response.nil? || @request_counter >= 100 response = @app.call(env) @cached_response = response.dup @remaining_count = extract_remaining_count(response) @request_counter = 0 response else response = @cached_response.dup update_remaining_count(response) Faraday::Response.new(response_env(env, response)) end end
def initialize(app)
-
app
(Object
) -- The next middleware in the stack
def initialize(app) super @cached_response = nil @remaining_count = nil @request_counter = 0 end
def response_env(env, response)
-
(Hash)
- Response environment hash
Parameters:
-
response
(Faraday::Response
) -- The cached response -
env
(Faraday::Env
) -- The original request environment
def response_env(env, response) headers = response.headers.dup headers['x-ratelimit-remaining'] = @remaining_count.to_s if @remaining_count { method: env.method, url: env.url, request_headers: env.request_headers, request_body: env.request_body, status: response.status, response_headers: headers, body: response.body } end
def track_request
def track_request return if @remaining_count.nil? @remaining_count -= 1 if @remaining_count.positive? @request_counter += 1 end
def update_remaining_count(response)
-
response
(Faraday::Response
) -- The cached response to update
def update_remaining_count(response) body = response.body original_was_string = body.is_a?(String) if original_was_string begin body = JSON.parse(body) rescue JSON::ParserError return end end return unless body.is_a?(Hash) && body['rate'] body['rate']['remaining'] = @remaining_count return unless original_was_string response.instance_variable_set(:@body, body.to_json) end