Commit 8eefd99c authored by Luke Duncalfe's avatar Luke Duncalfe

Expose GraphQL query complexity score

Allows the complexity score of a GraphQL query to be queryable by
clients:

    {
      queryComplexity {
        limit
        score
      }
    }

Changelog: added
parent 2e417fd5
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class QueryComplexityType < ::Types::BaseObject
ANALYZER = GraphQL::Analysis::QueryComplexity.new { |_query, complexity| complexity }
graphql_name 'QueryComplexity'
alias_method :query, :object
field :limit, GraphQL::INT_TYPE,
null: true,
method: :max_complexity,
see: {
'GitLab documentation on this limit' =>
'https://docs.gitlab.com/ee/api/graphql/index.html#max-query-complexity'
},
description: 'GraphQL query complexity limit.'
field :score, GraphQL::INT_TYPE,
null: true,
description: 'GraphQL query complexity score.'
def score
::GraphQL::Analysis.analyze_query(query, [ANALYZER]).first
end
end
# rubocop: enable Graphql/AuthorizeTypes
end
......@@ -36,6 +36,10 @@ module Types
resolver: Resolvers::MetadataResolver,
description: 'Metadata about GitLab.'
field :query_complexity, Types::QueryComplexityType,
null: true,
description: 'Information about the complexity of the GraphQL query.'
field :snippets,
Types::SnippetType.connection_type,
null: true,
......@@ -170,6 +174,10 @@ module Types
def application_settings
Gitlab::CurrentSettings.current_application_settings
end
def query_complexity
context.query
end
end
end
......
......@@ -298,6 +298,24 @@ query IssueTypes {
More about introspection:
[GraphQL documentation](https://graphql.org/learn/introspection/)
### Query complexity
The calculated [complexity score and limit](index.md#max-query-complexity) for a query can be revealed to clients by
querying for `queryComplexity`.
```graphql
query {
queryComplexity {
score
limit
}
project(fullPath: "gitlab-org/graphql-sandbox") {
name
}
}
```
## Sorting
Some of the GitLab GraphQL endpoints allow you to specify how to sort a
......
......@@ -166,7 +166,7 @@ The complexity of a single query is limited to a maximum of:
- `200` for unauthenticated requests.
- `250` for authenticated requests.
There is no way to discover the complexity of a query except by exceeding the limit.
The complexity score of a query and limit for the request [can be queried for](getting_started.md#query-complexity).
If a query exceeds the complexity limit an error message response will
be returned.
......
......@@ -286,6 +286,12 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="queryprojectssort"></a>`sort` | [`String`](#string) | Sort order of results. |
| <a id="queryprojectstopics"></a>`topics` | [`[String!]`](#string) | Filters projects by topics. |
### `Query.queryComplexity`
Information about the complexity of the GraphQL query.
Returns [`QueryComplexity`](#querycomplexity).
### `Query.runner`
Find a runner. Available only when feature flag `runner_graphql_query` is enabled.
......@@ -12335,6 +12341,15 @@ Pypi metadata.
| <a id="pypimetadataid"></a>`id` | [`PackagesPypiMetadatumID!`](#packagespypimetadatumid) | ID of the metadatum. |
| <a id="pypimetadatarequiredpython"></a>`requiredPython` | [`String`](#string) | Required Python version of the Pypi package. |
### `QueryComplexity`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="querycomplexitylimit"></a>`limit` | [`Int`](#int) | GraphQL query complexity limit. See [GitLab documentation on this limit](https://docs.gitlab.com/ee/api/graphql/index.html#max-query-complexity). |
| <a id="querycomplexityscore"></a>`score` | [`Int`](#int) | GraphQL query complexity score. |
### `RecentFailures`
Recent failure history of a test case.
......
......@@ -68,9 +68,7 @@ Complexity is explained [on our client-facing API page](../api/graphql/index.md#
Fields default to adding `1` to a query's complexity score, but developers can
[specify a custom complexity](#field-complexity) when defining a field.
To estimate the complexity of a query, you can run the
[`gitlab:graphql:analyze`](rake_tasks.md#analyze-graphql-queries)
Rake task.
The complexity score of a query [can itself be queried for](../api/graphql/getting_started.md#query-complexity).
### Request timeout
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['QueryComplexity'] do
include GraphqlHelpers
specify do
expect(described_class).to have_graphql_fields(:limit, :score).only
end
it 'works when executed' do
query = <<-GQL
query {
queryComplexity {
score
limit
}
currentUser {
name
}
}
GQL
query_result = run_with_clean_state(query).to_h
data = graphql_dig_at(query_result, :data, :queryComplexity)
expect(data).to include(
'score' => be > 0,
'limit' => GitlabSchema::DEFAULT_MAX_COMPLEXITY
)
end
end
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