Commit f8b94b64 authored by Luke Duncalfe's avatar Luke Duncalfe

Add docs for deprecating Global ID arguments

Documentation of how to deprecate Global ID arguments added in
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62870
parent 4439507e
......@@ -96,7 +96,7 @@ discussed in [Nullable fields](#nullable-fields).
Fields that use the [`feature_flag` property](#feature_flag-property) and the flag is disabled by default are exempt
from the deprecation process, and can be removed at any time without notice.
See the [deprecating fields and enum values](#deprecating-fields-arguments-and-enum-values) section for how to deprecate items.
See the [deprecating fields, arguments, and enum values](#deprecating-fields-arguments-and-enum-values) section for how to deprecate items.
## Global IDs
......@@ -110,6 +110,7 @@ See also:
- [Exposing Global IDs](#exposing-global-ids).
- [Mutation arguments](#object-identifier-arguments).
- [Deprecating Global IDs](#deprecating-global-ids).
We have a custom scalar type (`Types::GlobalIDType`) which should be used as the
type of input and output arguments when the value is a `GlobalID`. The benefits
......@@ -595,6 +596,105 @@ end
If the field, argument, or enum value being deprecated is not being replaced,
a descriptive deprecation `reason` should be given.
### Deprecating Global IDs
We use the [rails/globalid](https://github.com/rails/globalid) gem to generate and parse
Global IDs, so as such they are coupled to model names. This means that when we rename a
model it will change its Global ID.
If the Global ID is used as an _argument_ type anywhere in the schema then the Global ID
change would normally constitute a breaking change.
In order to continue to support clients using the old Global ID argument, we add a deprecation
to `Gitlab::GlobalId::Deprecations`.
NOTE:
If the Global ID is _only_ [exposed as a field](#exposing-global-ids) then we do not need to
deprecate it. We consider the change to the way a Global ID is expressed in a field to be
backwards-compatible as we expect that clients will not parse these values: they are meant to
be treated as opaque tokens, and any structure in them is incidental and not to be relied on.
**Example scenario:**
This example scenario is based on this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62645).
A model named `PrometheusService` is to be renamed `Integrations::Prometheus`. The old model
name is used to create a Global ID type that is used as an argument for a mutation:
```ruby
# Mutations::UpdatePrometheus:
argument :id, Types::GlobalIDType[::PrometheusService],
required: true,
description: "The ID of the integration to mutate."
```
Currently clients call the mutation by passing a Global ID string that looks like
`"gid://gitlab/PrometheusService/1"`, named as `PrometheusServiceID`, as the `input.id` argument:
```graphql
mutation updatePrometheus($id: PrometheusServiceID!, $active: Boolean!) {
prometheusIntegrationUpdate(input: { id: $id, active: $active }) {
errors
integration {
active
}
}
}
```
We rename the model to `Integrations::Prometheus`, and then update the codebase with the new name.
When we come to update the mutation, we pass the renamed model to `Types::GlobalIDType[]`:
```ruby
# Mutations::UpdatePrometheus:
argument :id, Types::GlobalIDType[::Integrations::Prometheus],
required: true,
description: "The ID of the integration to mutate."
```
This would cause a breaking change to the mutation, as the API will now reject clients who
pass an `id` argument as `"gid://gitlab/PrometheusService/1"`, or that specify the argument
type as `PrometheusServiceID` in the query signature.
To allow clients to continue to interact with the mutation unchanged, edit the `DEPRECATIONS` constant in
`Gitlab::GlobalId::Deprecations` and add a new `Deprecation` to the array:
```ruby
DEPRECATIONS = [
Deprecation.new(old_model_name: 'PrometheusService', new_model_name: 'Integrations::Prometheus', milestone: '14.0')
].freeze
```
Then follow our regular [deprecation process](../api/graphql/index.md#deprecation-and-removal-process). To later remove
support for the former argument style, remove the `Deprecation`:
```ruby
DEPRECATIONS = [].freeze
```
During the deprecation period the API will accept these values for the argument:
Formatted as either:
- `"gid://gitlab/PrometheusService/1"`
- `"gid://gitlab/Integrations::Prometheus/1"`
And query signatures will recognize the type under the old and new type names, accepting either:
- `PrometheusServiceID`
- `IntegrationsPrometheusID`
NOTE:
Although queries that use the old name (`PrometheusServiceID` in this example) would be
considered valid and executable by the API, validator tools would consider them invalid.
This is because we are deprecating using a bespoke method outside of the
[`@deprecated` directive](https://spec.graphql.org/June2018/#sec--deprecated), so validators are not
aware of the support.
The documentation will mention that the old Global ID style is now deprecated.
See also [Aliasing and deprecating mutations](#aliasing-and-deprecating-mutations).
## Enums
......@@ -1316,6 +1416,8 @@ 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`.
See also [Deprecating Global IDs](#deprecating-global-ids).
### Fields
In the most common situations, a mutation would return 2 fields:
......
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