Changing the Schema
The REST API from earlier manages breaking changes by putting a version in the base URL. It is possible to do the same with GraphQL, by running a second schema at a second URL, such as /graphql/v2, and letting each client pick one. However, this is almost never done in practice, because GraphQL is built around a single schema that changes in place.
Let’s first consider what kinds of changes to a GraphQL schema are safe and which ones break a client.
Adding a field to a type is safe. Since no existing query names the new field, no client is affected. Adding a type, or adding an optional argument to a field, is safe for the same reason. Making a returned field non-null is safe too, because the client already handles both a value and null, and now the field always has a value.
On the other hand, removing a field breaks every query that names it, because the server rejects those queries. Changing a field’s type breaks a client that parses the field as its old type. A client that assumes a field always has a value breaks when that field becomes nullable. Adding a required argument breaks every query that uses the field, since none of them provides it.
GraphQL handles breaking changes with deprecation. Instead of immediately removing a field or changing its type, the schema marks it as deprecated and provides a reason. This lets clients keep working while they move to the new field. Here is an example: suppose the quantity field on Product is being replaced by inStock.
type Product {
id: ID!
name: String!
quantity: Int! @deprecated(reason: "Use inStock.")
inStock: Int!
}
@deprecated marks the field that will be removed. Queries that name quantity keep working. At the same time, the API server logs uses of the deprecated field. When the logs show that no query has named the deprecated field for a set period, the field is removed. This works like the retirement date of a REST version, but for one field instead of a whole version. The cost is that the server keeps old fields working, and logs usage, until no client uses them. A REST API with a version in the base URL has a different cost. It has to run two versions at once.
The GraphQL approach to schema evolution allows for gradual changes without breaking existing clients, providing a more flexible and less disruptive way to manage API changes. It is generally considered a better alternative to traditional REST versioning.