Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
8aff254b
Commit
8aff254b
authored
Aug 10, 2020
by
Luke Duncalfe
Committed by
Evan Read
Aug 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clarify use of object identifiers in GraphQL API
parent
5a7553f7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
34 deletions
+78
-34
doc/api/graphql/audit_report.md
doc/api/graphql/audit_report.md
+2
-2
doc/api/graphql/getting_started.md
doc/api/graphql/getting_started.md
+3
-2
doc/development/api_graphql_styleguide.md
doc/development/api_graphql_styleguide.md
+73
-30
No files found.
doc/api/graphql/audit_report.md
View file @
8aff254b
...
@@ -8,8 +8,8 @@ guidance on getting started from the [command line](getting_started.md#command-l
...
@@ -8,8 +8,8 @@ guidance on getting started from the [command line](getting_started.md#command-l
The
[
example users query
](
#set-up-the-graphiql-explorer
)
looks for a subset of users in
The
[
example users query
](
#set-up-the-graphiql-explorer
)
looks for a subset of users in
a GitLab instance either by username or
a GitLab instance either by username or
[
global ID
](
../../development/api_graphql_styleguide.md#exposing-global-ids
)
. The query
[
Global ID
](
../../development/api_graphql_styleguide.md#global-ids
)
.
includes:
The query
includes:
-
[
`pageInfo`
](
#pageinfo
)
-
[
`pageInfo`
](
#pageinfo
)
-
[
`nodes`
](
#nodes
)
-
[
`nodes`
](
#nodes
)
...
...
doc/api/graphql/getting_started.md
View file @
8aff254b
...
@@ -59,8 +59,9 @@ The GitLab GraphQL API can be used to perform:
...
@@ -59,8 +59,9 @@ The GitLab GraphQL API can be used to perform:
-
[
Mutations
](
#mutations
)
for creating, updating, and deleting data.
-
[
Mutations
](
#mutations
)
for creating, updating, and deleting data.
NOTE:
**Note:**
NOTE:
**Note:**
In the GitLab GraphQL API,
`id`
generally refers to a global ID,
In the GitLab GraphQL API,
`id`
refers to a
which is an object identifier in the format of
`gid://gitlab/Issue/123`
.
[
Global ID
](
https://graphql.org/learn/global-object-identification/
)
,
which is an object identifier in the format of
`"gid://gitlab/Issue/123"`
.
[
GitLab's GraphQL Schema
](
reference/index.md
)
outlines which objects and fields are
[
GitLab's GraphQL Schema
](
reference/index.md
)
outlines which objects and fields are
available for clients to query and their corresponding data types.
available for clients to query and their corresponding data types.
...
...
doc/development/api_graphql_styleguide.md
View file @
8aff254b
...
@@ -36,6 +36,19 @@ can be shared.
...
@@ -36,6 +36,19 @@ can be shared.
It is also possible to add a
`private_token`
to the querystring, or
It is also possible to add a
`private_token`
to the querystring, or
add a
`HTTP_PRIVATE_TOKEN`
header.
add a
`HTTP_PRIVATE_TOKEN`
header.
## Global IDs
GitLab's GraphQL API uses Global IDs (i.e:
`"gid://gitlab/MyObject/123"`
)
and never database primary key IDs.
Global ID is
[
a standard
](
https://graphql.org/learn/global-object-identification/
)
used for caching and fetching in client-side libraries.
See also:
-
[
Exposing Global IDs
](
#exposing-global-ids
)
.
-
[
Mutation arguments
](
#object-identifier-arguments
)
.
## Types
## Types
We use a code-first schema, and we declare what type everything is in Ruby.
We use a code-first schema, and we declare what type everything is in Ruby.
...
@@ -106,18 +119,28 @@ Further reading:
...
@@ -106,18 +119,28 @@ Further reading:
### Exposing Global IDs
### Exposing Global IDs
When exposing an
`ID`
field on a type, we will by default try to
In keeping with GitLab's use of
[
Global IDs
](
#global-ids
)
, always convert
expose a global ID by calling
`to_global_id`
on the resource being
database primary key IDs into Global IDs when you expose them.
rendered.
All fields named
`id`
are
[
converted automatically
](
https://gitlab.com/gitlab-org/gitlab/-/blob/b0f56e7/app/graphql/types/base_object.rb#L11-14
)
into the object's Global ID.
To override this behavior, you can implement an
`id`
method on the
Fields that are not named
`id`
need to be manually converted. We can do this using
type for which you are exposing an ID. Please make sure that when
[
`Gitlab::GlobalID.build`
](
https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/global_id.rb
)
,
exposing a
`GraphQL::ID_TYPE`
using a custom method that it is
or by calling
`#to_global_id`
on an object that has mixed in the
globally uniqu
e.
`GlobalID::Identification`
modul
e.
The records that are exposing a
`full_path`
as an
`ID_TYPE`
are one of
Using an example from
these exceptions. Since the full path is a unique identifier for a
[
`Types::Notes::DiscussionType`
](
https://gitlab.com/gitlab-org/gitlab/-/blob/3c95bd9/app/graphql/types/notes/discussion_type.rb#L24-26
)
:
`Project`
or
`Namespace`
.
```
ruby
field
:reply_id
,
GraphQL
::
ID_TYPE
def
reply_id
::
Gitlab
::
GlobalId
.
build
(
object
,
id:
object
.
reply_id
)
end
```
### Connection Types
### Connection Types
...
@@ -654,15 +677,8 @@ the objects in question.
...
@@ -654,15 +677,8 @@ the objects in question.
To find objects to display in a field, we can add resolvers to
To find objects to display in a field, we can add resolvers to
`app/graphql/resolvers`
.
`app/graphql/resolvers`
.
Arguments can be defined within the resolver, those arguments will be
Arguments can be defined within the resolver in the same way as in a mutation.
made available to the fields using the resolver. When exposing a model
See the
[
Mutation arguments
](
#object-identifier-arguments
)
section.
that had an internal ID (
`iid`
), prefer using that in combination with
the namespace path as arguments in a resolver over a database
ID. Otherwise use a
[
globally unique ID
](
#exposing-global-ids
)
.
We already have a
`FullPathLoader`
that can be included in other
resolvers to quickly find Projects and Namespaces which will have a
lot of dependent objects.
To limit the amount of queries performed, we can use
`BatchLoader`
.
To limit the amount of queries performed, we can use
`BatchLoader`
.
...
@@ -751,10 +767,6 @@ actions. In the same way a GET-request should not modify data, we
...
@@ -751,10 +767,6 @@ actions. In the same way a GET-request should not modify data, we
cannot modify data in a regular GraphQL-query. We can however in a
cannot modify data in a regular GraphQL-query. We can however in a
mutation.
mutation.
To find objects for a mutation, arguments need to be specified. As with
[
resolvers
](
#resolvers
)
, prefer using internal ID or, if needed, a
global ID rather than the database ID.
### Building Mutations
### Building Mutations
Mutations live in
`app/graphql/mutations`
ideally grouped per
Mutations live in
`app/graphql/mutations`
ideally grouped per
...
@@ -809,10 +821,34 @@ If you need advice for mutation naming, canvass the Slack `#graphql` channel for
...
@@ -809,10 +821,34 @@ If you need advice for mutation naming, canvass the Slack `#graphql` channel for
### Arguments
### Arguments
Arguments required by the mutation can be defined as arguments
Arguments for a mutation are defined using
`argument`
.
required for a field. These will be wrapped up in an input type for
the mutation. For example, the
`Mutations::MergeRequests::SetWip`
Example:
with GraphQL-name
`MergeRequestSetWip`
defines these arguments:
```
ruby
argument
:my_arg
,
GraphQL
::
STRING_TYPE
,
required:
true
,
description:
"A description of the argument"
```
Each GraphQL
`argument`
defined will be passed to the
`#resolve`
method
of a mutation as keyword arguments.
Example:
```
ruby
def
resolve
(
my_arg
:)
# Perform mutation ...
end
```
`graphql-ruby`
will automatically wrap up arguments into an
[
input type
](
https://graphql.org/learn/schema/#input-types
)
.
For example, the
[
`mergeRequestSetWip` mutation
](
https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/set_wip.rb
)
defines these arguments (some
[
through inheritance
](
https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/base.rb
)
):
```
ruby
```
ruby
argument
:project_path
,
GraphQL
::
ID_TYPE
,
argument
:project_path
,
GraphQL
::
ID_TYPE
,
...
@@ -832,12 +868,19 @@ argument :wip,
...
@@ -832,12 +868,19 @@ argument :wip,
DESC
DESC
```
```
Th
is would
automatically generate an input type called
Th
ese arguments
automatically generate an input type called
`MergeRequestSetWipInput`
with the 3 arguments we specified and the
`MergeRequestSetWipInput`
with the 3 arguments we specified and the
`clientMutationId`
.
`clientMutationId`
.
These arguments are then passed to the
`resolve`
method of a mutation
### Object identifier arguments
as keyword arguments.
In keeping with GitLab's use of
[
Global IDs
](
#global-ids
)
, mutation
arguments should use Global IDs to identify an object and never database
primary key IDs.
Where an object has an
`iid`
, prefer to use the
`full_path`
or
`group_path`
of its parent in combination with its
`iid`
as arguments to identify an
object rather than its
`id`
.
### Fields
### Fields
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment