Operation Checks
APIs evolve. Most of the time, changes are additive: a new mutation, a new field on a type, or new input objects for filtering collections, for example. These changes changes can be safely made without breaking consumers of the API.
Other changes, however, will break clients that send queries written for a previous version of the API. Common examples would be the removal of a field, or adding a required argument on a field. These changes are disruptive, because all GraphQL servers will reject invalid GraphQL queries that cannot be executed on the present version of the schema.
Operation Checks are Schema Checks that exist to help you avoid breaking clients when making changes to your GraphQL schema. Concretely, they are rules that can manifest breaking changes as errors when you run grafbase check
.
For a change to be breaking, two criteria must be met:
- The change is theoretically breaking. See list of breaking changes.
- The part of the schema that changed or disappeared is in use by clients.
Without the second criterion, Operation Checks would be too strict. You would not be free to iterate on any part of your schema that has ever been published, even when it is not used yet or not used anymore. Operation checks take advantage of request analytics to only take into account the actual usage of your API, and not only theoretically breaking changes.
Operation Checks are opt-in. They are configured in the dashboard.
You can enable them for your whole graph, on only for specific branches. You can select how many queries are required to use a part of your schema for it to be used, and in which time frame.
You can exclude specific operations by name. For example, in the following GraphQL document, the operation name is "JapaneseProducts":
query JapaneseProducts {
products(filter: { madeIn: "JP" }) {
id
name
}
}
Specific clients can also be excluded. The client name is identified by the value of the custom x-grafbase-client-name
header, and self-reported by clients. You can include the client name as a regular HTTP header in your GraphQL client of choice and it will simply work.
As a part of schema checks, they are run whenever you use the grafbase check
command. The checks errors will point out breaking changes that would result from deploying the schema you passed to grafbase check
to the branch you check against. The real-world client usage data is the usage data collected for the target branch.
Below is a list of the changes considered as potentially breaking:
- Removal of a root query, mutation or subscription type.
- Removal of an object, interface or input object field.
- Removal of a field argument.
- Removal of an interface from
implements
. - Removal of a member type in a union.
- Removal of a value of an enum.
- Addition of a nonnullable argument on a field.
- Addition of a nonnullable field on an input object.
- Change of a field's type.
- Either change of the inner type:
String
becomingInt
for example, - or a change of wrapping types making the field nullable:
String!
toString
or[String!]
to[String]
for example. The client would not expect null here.
- Either change of the inner type:
- Change of a field argument's type.
- Either change of the inner type:
String
becomingInt
for example, - or a change of wrapping types making the argument nonnullable:
String
toString!
or[String]
to[String!]
for example. The client could be passing null.
- Either change of the inner type:
- Removal of a field argument's default, if the argument is required.
For all of these, we check actual usage before triggering an Operation Check error.