Commit 6d9eb344 authored by Robert May's avatar Robert May

Rate-limited action caching for branches API

parent aa389f6a
---
name: api_caching_rate_limit_branches
introduced_by_url:
rollout_issue_url:
milestone: '13.12'
type: development
group: group::source code
default_enabled: false
...@@ -38,6 +38,9 @@ module API ...@@ -38,6 +38,9 @@ module API
optional :page_token, type: String, desc: 'Name of branch to start the paginaition from' optional :page_token, type: String, desc: 'Name of branch to start the paginaition from'
end end
get ':id/repository/branches' do get ':id/repository/branches' do
ff_enabled = Feature.enabled?(:api_caching_rate_limit_branches, user_project, default_enabled: :yaml)
cache_action_if(ff_enabled, [user_project, :branches, current_user&.cache_key, params], expires_in: 30.seconds) do
user_project.preload_protected_branches user_project.preload_protected_branches
repository = user_project.repository repository = user_project.repository
...@@ -67,6 +70,7 @@ module API ...@@ -67,6 +70,7 @@ module API
) )
end end
end end
end
resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do
desc 'Get a single branch' do desc 'Get a single branch' do
......
...@@ -63,6 +63,32 @@ module API ...@@ -63,6 +63,32 @@ module API
body Gitlab::Json::PrecompiledJson.new(json) body Gitlab::Json::PrecompiledJson.new(json)
end end
# Action caching implementation
#
# This allows you to wrap an entire API endpoint call in a cache, useful
# for short TTL caches to effectively rate-limit an endpoint.
#
# @param key [Object] any object that can be converted into a cache key
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
# @return [Gitlab::Json::PrecompiledJson]
def cache_action(key, **cache_opts)
json = cache.fetch(key, **cache_opts) do
Gitlab::Json.dump(yield.as_json)
end
body Gitlab::Json::PrecompiledJson.new(json)
end
def cache_action_if(conditional, *opts)
if conditional
cache_action(*opts) do
yield
end
else
yield
end
end
private private
# Optionally uses a `Proc` to add context to a cache key # Optionally uses a `Proc` to add context to a cache key
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment