Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First draft for upgrade guide to v17 #4310

Draft
wants to merge 1 commit into
base: 16.x.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions website/pages/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const meta = {
'oneof-input-objects': 'OneOf input objects',
'defer-stream': '',
'-- 3': {
type: 'separator',
title: 'Upgrade guides',
},
'v16-v17': '',
'-- 4': {
type: 'separator',
title: 'FAQ',
},
Expand Down
129 changes: 129 additions & 0 deletions website/pages/v16-v17.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: Upgrading from v16 to v17
sidebarTitle: v16 to v17
---

import { Tabs } from 'nextra/components';

# Breaking changes

## Default values

Previously default-values were assumed to be coerced internal values, now
we will treat them like a pre-coerced external input value. This equalises
how we treat default-values in SDL and variables over JSON.

This goes hand-in-hand with the deprecation of `astFromValue` in favor of `valueToLiteral`.

## GraphQLError constructor arguments

The `GraphQLError` constructor now only accepts a message and options object as arguments. Previously, it also accepted positional arguments.

```diff
- new GraphQLError('message', 'source', 'positions', 'path', 'originalError', 'extensions');
+ new GraphQLError('message', { source, positions, path, originalError, extensions });
```

## `createSourceEventStream` arguments

The `createSourceEventStream` function now only accepts an object as an argument. Previously, it also accepted positional arguments.

```diff
- createSourceEventStream(schema, document, rootValue, contextValue, variableValues, operationName);
+ createSourceEventStream({ schema, document, rootValue, contextValue, variableValues, operationName });
```

## `execute` will error for incremental delivery

The `execute` function will now throw an error if it sees a `@defer` or `@stream` directive. Use `experimentalExecuteIncrementally` instead.
If you know you are dealing with incremental delivery requests, you can replace the import.

```diff
- import { execute } from 'graphql';
+ import { experimentalExecuteIncrementally as execute } from 'graphql';
```

## Remove incremental delivery support from `subscribe`

In case you have fragments that you use with `defer/stream` that end up in a subscription,
use the `if` argument of the directive to disable it in your subscription operation

## `subscribe` return type

The `subscribe` function can now also return a non-Promise value, previously this was only a Promise.
This shouldn't change a lot as `await value` will still work as expected. This could lead to
some typing inconsistencies though.

## Remove `singleResult` from incremental results

You can remove branches that check for `singleResult` in your code, as it is no longer used.

## Node support

Dropped support for Node 14 (subject to change)

## Removed `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types

We have removed the `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types,
use `Kind`, `TokenKind` and `DirectiveLocation` instead. https://github.com/graphql/graphql-js/pull/3579

## Removed `graphql/subscription` module

use `graphql/execution` instead for subscriptions, all execution related exports have been
unified there.

## Removed `GraphQLInterfaceTypeNormalizedConfig` export

Use `ReturnType<GraphQLInterfaceType['toConfig']>` if you really need this

## Empty AST collections will be undefined

Empty AST collections will be presented by `undefined` rather than an empty array.

## `Info.variableValues`

The shape of `Info.variableValues` has changed to be an object containing
`sources` and `coerced` as keys.

A Source contains the `signature` and provided `value` pre-coercion for the
variable. A `signature` is an object containing the `name`, `input-type` and
`defaultValue` for the variable.

## Removals

- Removed exported `getOperationType` function
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed exported `getOperationType` function
- Removed deprecated `getOperationType` function, use instead the `getRootType()` method on the
appropriate `GraphQLSchema` object.

- Removed exported `getVisitFn` function
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed exported `getVisitFn` function
- Removed deprecated `getVisitFn` function, use `getEnterLeaveForKind` instead.

- Removed exported `printError` and `formatError` utilities
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed exported `printError` and `formatError` utilities
- Removed deprecated `printError` and `formatError` utilities, use instead the `toString` and `toJSON` methods on the desired `GraphQLError` object.

- Removed exported `assertValidName` and `isValidNameError` utilities
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed exported `assertValidName` and `isValidNameError` utilities
- Removed deprecated `assertValidName` and `isValidNameError` utilities, convert to `assertName`.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a standard of doing empty braces? Feels a bit redundant

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed, to each their own!

- Removed exported `assertValidExecutionArguments` function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed exported `assertValidExecutionArguments` function
- Removed deprecated function `assertValidExecutionArguments()` function, use `assertValidSchema()` to validate the schema.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't actually deprecated this in v16 I think, I will submit a PR to do this. All the additional checks in that function are now just performed by TS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- Removed `getFieldDefFn` from `TypeInfo`
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed `getFieldDefFn` from `TypeInfo`
- Removed deprecated `getFieldDefFn` method from `TypeInfo`. If you really need to customize field resolution, you can subclass the `GraphQLSchema` class and override the `getField` method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would heavily avoid subjective strengtheners like truly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched it to the "if you really need this" construction used elsewhere

- Removed `TypeInfo` from `validate` https://github.com/graphql/graphql-js/pull/4187
Copy link
Contributor

@yaacovCR yaacovCR Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Removed `TypeInfo` from `validate` https://github.com/graphql/graphql-js/pull/4187
- Removed deprecated `TypeInfo` argument from `validate`, this was previously used to support non-specified validation behavior that is explicitly discouraged; custom behavior can be better obtained by using custom rules.

I removed the reference to the PR which has no additional info, and we didn't link to PRs generally, but it's fine really to keep.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, the PR's having no context is its own issue. You're right though, none of the PR's give the context we require to pick all of this up. Not sure whether we need to specify whether it was deprecated though, I don't think that matters at all

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advantage of sprinkling the word deprecating in is that it hopefully gives the reader the (correct) understanding that although the list of breaking changes may be lengthy, it is shorter if they are not using deprecated functionality. This might be immediately helpful to those who know that they are not using deprecated functionality and might encourage those still using deprecated functionality to migrate off of it if they have not done so. I have changed elsewhere exported to deprecated as a one word change that gives this impression as a whole. Here I am adding the one word for consistency.

In terms of the no context on the linked PR, that is certainly my bad as it is mine, I take that constructive criticism, will try to improve in the future. I have edited suggestion above to give more context inline.


## Deprecations

- Deprecated `astFromValue` use `valueToLiteral` instead, when leveraging `valueToLiteral` ensure
that you are working with externally provided values i.e. the SDL provided defaultValue to a variable.
- Deprecated `valueFormAST` use `coerceInputLiteral` instead

## New Features

- Added `hideSuggestions` option to `execute`/`validate`/`subscribe`/... to hide schema-suggestions in error messages
- Added `abortSignal` option to `graphql()`, `execute()`, and `subscribe()` allows cancellation of these methods;
the `abortSignal` can also be passed to field resolvers to cancel asynchronous work that they initiate.
- `extensions` support `symbol` keys, in addition to the normal string keys.

## New Experimental Features

### Experimental Support for Incremental Delivery

- [Spec PR](https://github.com/graphql/graphql-spec/pull/1110) / [RFC](https://github.com/graphql/graphql-wg/blob/main/rfcs/DeferStream.md)
- enabled only when using `experimentalExecuteIncrementally()`, use of a schema or operation with `@defer`/`@stream` directives within `execute()` will now throw.
- enable early execution with the new `enableEarlyExecution` configuration option for `experimentalExecuteIncrementally()`.

### Experimental Support for Fragment Arguments

- [Spec PR](https://github.com/graphql/graphql-spec/pull/1081)
- enable with the new `experimentalFragmentArguments` configuration option for `parse()`.
- new experimental `Kind.FRAGMENT_ARGUMENT` for visiting
- new experimental `TypeInfo` methods and options for handling fragment arguments.
- coerce AST via new function `coerceInputLiteral()` with experimental fragment variables argument (as opposed to deprecated `valueFromAST()` function).
Loading