Class: GitlabSchema

Inherits:
GraphQL::Schema
  • Object
show all
Defined in:
app/graphql/gitlab_schema.rb

Constant Summary collapse

DEFAULT_MAX_COMPLEXITY =
200
AUTHENTICATED_MAX_COMPLEXITY =
250
ADMIN_MAX_COMPLEXITY =
300
INTROSPECTION_MAX_COMPLEXITY =

Current GraphiQL introspection query has complexity of 226. As we cache this specific query we allow it to have a higher complexity.

226
DEFAULT_MAX_DEPTH =
15
AUTHENTICATED_MAX_DEPTH =
20

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_by_gid(gid) ⇒ Object

Find an object by looking it up from its ‘GlobalID’.

  • For ‘ApplicationRecord`s, this is equivalent to `global_id.model_class.find(gid.model_id)`, but more efficient.

  • For classes that implement ‘.lazy_find(global_id)`, this class method will be called.

  • All other classes will use ‘GlobalID#find`



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/graphql/gitlab_schema.rb', line 97

def find_by_gid(gid)
  return unless gid

  if gid.model_class < ApplicationRecord
    Gitlab::Graphql::Loaders::BatchModelLoader.new(gid.model_class, gid.model_id).find
  elsif gid.model_class.respond_to?(:lazy_find)
    gid.model_class.lazy_find(gid.model_id)
  else
    begin
      gid.find
    # other if conditions return nil when the record is not found
    rescue ActiveRecord::RecordNotFound, ActiveRecord::FixedItemsModel::RecordNotFound
      nil
    end
  end
end

.get_type(type_name, *other_args) ⇒ Object



52
53
54
55
56
57
# File 'app/graphql/gitlab_schema.rb', line 52

def get_type(type_name, *other_args)
  type_name = Gitlab::GlobalId::Deprecations.apply_to_graphql_name(type_name)
  type_name = Gitlab::Graphql::TypeNameDeprecations.apply_to_graphql_name(type_name)

  super(type_name, *other_args)
end

.id_from_object(object, _type = nil, _ctx = nil) ⇒ Object



59
60
61
62
63
64
65
66
67
68
# File 'app/graphql/gitlab_schema.rb', line 59

def id_from_object(object, _type = nil, _ctx = nil)
  unless object.respond_to?(:to_global_id)
    # This is an error in our schema and needs to be solved. So raise a
    # more meaningful error message
    raise "#{object} does not implement `to_global_id`. " \
      "Include `GlobalID::Identification` into `#{object.class}"
  end

  object.to_global_id
end

.multiplex(queries, **kwargs) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'app/graphql/gitlab_schema.rb', line 41

def multiplex(queries, **kwargs)
  kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context]) unless kwargs.key?(:max_complexity)

  queries.each do |query|
    query[:max_complexity] ||= max_query_complexity(query[:context]) unless query.key?(:max_complexity)
    query[:max_depth] = max_query_depth(query[:context]) unless query.key?(:max_depth)
  end

  super(queries, **kwargs)
end

.object_from_id(global_id, ctx = {}) ⇒ Object

Find an object by looking it up from its global ID, passed as a string.

This is the composition of ‘parse_gid’ and ‘find_by_gid’, see these methods for further documentation.



74
75
76
77
78
# File 'app/graphql/gitlab_schema.rb', line 74

def object_from_id(global_id, ctx = {})
  gid = parse_gid(global_id, ctx)

  find_by_gid(gid)
end

.parse_gid(global_id, ctx = {}) ⇒ Object

Parse a string to a GlobalID, raising ArgumentError if there are problems with it.

Problems that may occur:

* it may not be syntactically valid
* it may not match the expected type (see below)

Options:

* :expected_type [Class] - the type of object this GlobalID should refer to.
* :expected_type [[Class]] - array of the types of object this GlobalID should refer to.

e.g.

“‘

gid = GitlabSchema.parse_gid(my_string, expected_type: ::Project)
project_id = gid.model_id
gid.model_class == ::Project

“‘



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'app/graphql/gitlab_schema.rb', line 132

def parse_gid(global_id, ctx = {})
  expected_types = Array(ctx[:expected_type])
  gid = GlobalID.parse(global_id)

  raise Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab ID." unless gid

  if expected_types.any? && expected_types.none? { |type| gid.model_class.ancestors.include?(type) }
    vars = { global_id: global_id, expected_types: expected_types.join(', ') }
    msg = _('%{global_id} is not a valid ID for %{expected_types}.') % vars
    raise Gitlab::Graphql::Errors::ArgumentError, msg
  end

  gid
end

.parse_gids(global_ids, ctx = {}) ⇒ Object

Parse an array of strings to an array of GlobalIDs, raising ArgumentError if there are problems with it. See #parse_gid

“‘

gids = GitlabSchema.parse_gids(my_array_of_strings, expected_type: ::Project)
project_ids = gids.map(&:model_id)
gids.all? { |gid| gid.model_class == ::Project }

“‘



156
157
158
# File 'app/graphql/gitlab_schema.rb', line 156

def parse_gids(global_ids, ctx = {})
  global_ids.map { |gid| parse_gid(gid, ctx) }
end

.resolve_type(type, object, ctx = :__undefined__) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'app/graphql/gitlab_schema.rb', line 80

def resolve_type(type, object, ctx = :__undefined__)
  return if type.respond_to?(:assignable?) && !type.assignable?(object)

  if type.kind.object?
    type
  else
    super
  end
end

.unauthorized_field(error) ⇒ Object



160
161
162
163
164
# File 'app/graphql/gitlab_schema.rb', line 160

def unauthorized_field(error)
  return error.field.if_unauthorized if error.field.respond_to?(:if_unauthorized) && error.field.if_unauthorized

  super
end

Instance Method Details

#get_type(type_name) ⇒ Object



194
195
196
197
198
199
# File 'app/graphql/gitlab_schema.rb', line 194

def get_type(type_name)
  type_name = Gitlab::GlobalId::Deprecations.apply_to_graphql_name(type_name)
  type_name = Gitlab::Graphql::TypeNameDeprecations.apply_to_graphql_name(type_name)

  super(type_name)
end