diff options
author | Phil Hughes <me@iamphill.com> | 2019-05-09 12:27:07 +0300 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2019-05-28 11:22:02 +0300 |
commit | 11f85ae8c3b8ec5d864edd079e7c420a49cae72e (patch) | |
tree | 8da63219fc0977c7e132f7177bff20f41c997520 /app | |
parent | 2cc6e6ff2628bd71faa71f083646a981ab2bcc11 (diff) |
Enables GraphQL batch requests
Enabling GraphQL batch requests allows for multiple queries
to be sent in 1 request reducing the amount of requests
we send to the server.
Responses come come back in the same order as the queries were
provided.
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/graphql_controller.rb | 46 | ||||
-rw-r--r-- | app/graphql/gitlab_schema.rb | 15 |
2 files changed, 52 insertions, 9 deletions
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 7b5dc22815c..e8f38899647 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -16,13 +16,8 @@ class GraphqlController < ApplicationController before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } def execute - variables = Gitlab::Graphql::Variables.new(params[:variables]).to_h - query = params[:query] - operation_name = params[:operationName] - context = { - current_user: current_user - } - result = GitlabSchema.execute(query, variables: variables, context: context, operation_name: operation_name) + result = multiplex? ? execute_multiplex : execute_query + render json: result end @@ -38,6 +33,43 @@ class GraphqlController < ApplicationController private + def execute_multiplex + GitlabSchema.multiplex(multiplex_queries, context: context) + end + + def execute_query + variables = build_variables(params[:variables]) + operation_name = params[:operationName] + + GitlabSchema.execute(query, variables: variables, context: context, operation_name: operation_name) + end + + def query + params[:query] + end + + def multiplex_queries + params[:_json].map do |single_query_info| + { + query: single_query_info[:query], + variables: build_variables(single_query_info[:variables]), + operation_name: single_query_info[:operationName] + } + end + end + + def context + @context ||= { current_user: current_user } + end + + def build_variables(variable_info) + Gitlab::Graphql::Variables.new(variable_info).to_h + end + + def multiplex? + params[:_json].present? + end + def authorize_access_api! access_denied!("API not accessible for user.") unless can?(current_user, :access_api) end diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index 897e12c1b56..a63f45f231c 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -7,7 +7,7 @@ class GitlabSchema < GraphQL::Schema AUTHENTICATED_COMPLEXITY = 250 ADMIN_COMPLEXITY = 300 - ANONYMOUS_MAX_DEPTH = 10 + DEFAULT_MAX_DEPTH = 10 AUTHENTICATED_MAX_DEPTH = 15 use BatchLoader::GraphQL @@ -23,10 +23,21 @@ class GitlabSchema < GraphQL::Schema default_max_page_size 100 max_complexity DEFAULT_MAX_COMPLEXITY + max_depth DEFAULT_MAX_DEPTH mutation(Types::MutationType) class << self + def multiplex(queries, **kwargs) + kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context]) + + queries.each do |query| + query[:max_depth] = max_query_depth(kwargs[:context]) + end + + super(queries, **kwargs) + end + def execute(query_str = nil, **kwargs) kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context]) kwargs[:max_depth] ||= max_query_depth(kwargs[:context]) @@ -54,7 +65,7 @@ class GitlabSchema < GraphQL::Schema if current_user AUTHENTICATED_MAX_DEPTH else - ANONYMOUS_MAX_DEPTH + DEFAULT_MAX_DEPTH end end end |