Open-Source Wikis

/

GitLab

/

API

/

GraphQL API

gitlab-org/gitlab

GraphQL API

GitLab's GraphQL endpoint at /api/graphql, with subscriptions at /api/graphql_subscriptions. Most newer features expose data via GraphQL first.

Source

app/graphql/
├── gitlab_schema.rb             # The schema; assembles types, mutations, subscriptions
├── batch_loaders/                # BatchLoader pre-loaders
├── directives/                   # Custom directives
├── graphql_triggers.rb           # Subscription trigger registry
├── mutations/                    # ~30 namespaces of mutations
├── queries/                      # File-based query helpers
├── resolvers/                    # ~40 namespaces of field resolvers
├── subscriptions/                # Subscription definitions
├── types/                        # ~80 namespaces of types
├── cached_introspection_query.rb
└── ...
ee/app/graphql/                   # EE additions

The graphql-ruby gem powers the schema. Custom GitLab additions:

  • Scope-aware authorization at the field level.
  • Complexity scoring with hard limits.
  • Polymorphic Apollo-style cache hints.
  • Action Cable transport for subscriptions.
  • BatchLoader for N+1-free traversal.

Schema

The main schema is GitlabSchema (app/graphql/gitlab_schema.rb). EE features prepend onto it.

Schema artifacts:

  • bin/rake gitlab:graphql:schema:dump produces tmp/tests/graphql/gitlab_schema.graphql (and .json).
  • The persisted SDL ships as a CI artifact; clients (Apollo codegen, the Web IDE) consume it.
  • Schema breaking changes are flagged by Gitlab::Graphql::CompatibilityCheck in CI.

Conventions

  • Types are camelCased on the GraphQL side and snake_cased server-side (graphql-ruby handles the mapping).
  • Field-level authorization uses authorize: :ability_name, which calls declarative_policy.
  • Mutations follow the Relay convention: MutationInput { clientMutationId, ... }, return MutationPayload.
  • Connections use Relay-style cursor pagination.

Mutations

module Mutations
  module Projects
    class Update < BaseMutation
      graphql_name 'ProjectUpdate'
      authorize :admin_project

      argument :id, ::Types::GlobalIDType[::Project], required: true
      argument :description, GraphQL::Types::String, required: false

      field :project, ::Types::ProjectType, null: true

      def resolve(id:, **args)
        project = authorized_find!(id: id)
        result = ::Projects::UpdateService.new(project, current_user, args).execute
        # …
      end
    end
  end
end

Subscriptions

graphql_triggers.rb declares trigger functions that producers call:

GraphqlTriggers.issuable_assignees_updated(issue)

Subscribers use Action Cable as the transport; app/channels/graphql_channel.rb routes incoming subscription requests.

Complexity limits

Every field has a complexity score. The total per query is capped (~250 by default; logged-out users have a lower cap). The Gitlab::Graphql::ComplexityAnalyzer enforces this and emits Prometheus metrics.

Persisted queries

GitLab.com supports persisted queries (introspection-cached) via the cached_introspection_query.rb helper. The frontend ships a hashed query manifest; the server validates against it.

Where to make changes

  • New type: under app/graphql/types/<area>/. Always set graphql_name and a description.
  • New mutation: under app/graphql/mutations/<area>/<verb>.rb. Subclass BaseMutation and use authorize.
  • New subscription: declare in graphql_triggers.rb and the subscriptions namespace.
  • New resolver: under app/graphql/resolvers/<area>/. Use BatchLoader::GraphQL for N+1.

Testing

  • Request specs under spec/requests/api/graphql/.
  • Resolver specs under spec/graphql/resolvers/.
  • Mutation specs under spec/graphql/mutations/.
  • Helpers in spec/support/helpers/graphql_helpers.rb.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

GraphQL API – GitLab wiki | Factory