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

Make AS/ASP invariant in TContext; move logger/cache to server in plugins #6668

Merged
merged 1 commit into from
Jul 12, 2022

Conversation

glasser
Copy link
Member

@glasser glasser commented Jul 12, 2022

This change does two things, which we originally thought were kind of
connected but maybe aren't.

First, we switch the implementation of contravariance from a hacky
__forceTContextToBeContravariant field to the new TS 4.7 variance
annotations. But in fact, instead of making it contravariant, we make it
invariant: ApolloServer<X> can only be assigned to ApolloServer<Y>
when X and Y are the same. This is because:

  • An ApolloServer<{foo: number}> is not a ApolloServer<{}>, because
    you can invoke executeOperation on the latter with an empty context
    object, which would confuse the former (this is the contravariance we
    already had).
  • An ApolloServer<{}> is not a ApolloServer<{foo: number}>, because
    you can invoke addPlugin on the latter with a plugin whose methods
    expect to be called with a contextValue with {foo: number} on it,
    which isn't the case for the former.

Considering the second condition is why this is now invariant (in out). We're not quite sure why TS couldn't figure this out for us, but
it can't.

Second, we add server: ApolloServer to various plugin hook arguments
(GraphQLRequestContext and GraphQLServerContext). This makes
logger and cache on GraphQLRequestContext somewhat redundant, so
we make those fields into public readonly fields on ApolloServer and
remove them from the plugin hook arguments. (We thought this was related
to the other part because adding server appeared to require invariance
instead of contravariance, but it turns out that we needed invariance
anyway due to addPlugin.)

Note that this means that anyone consuming our .d.ts files must be on
TS4.7. Before v4.0.0 we'll probably fix that; see #6423.

Fixes #6264. Fixes #6082.

@changeset-bot
Copy link

changeset-bot bot commented Jul 12, 2022

⚠️ No Changeset found

Latest commit: 99303ac

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link

netlify bot commented Jul 12, 2022

Deploy Preview for apollo-server-docs failed.

Name Link
🔨 Latest commit 99303ac
🔍 Latest deploy log https://app.netlify.com/sites/apollo-server-docs/deploys/62ccd01a71707b0009bb10cd

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 12, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 99303ac:

Sandbox Source
Apollo Server Typescript Configuration
Apollo Server Configuration

…gins

This change does two things, which we originally thought were kind of
connected but maybe aren't.

First, we switch the implementation of contravariance from a hacky
`__forceTContextToBeContravariant` field to the new TS 4.7 variance
annotations. But in fact, instead of making it contravariant, we make it
invariant: `ApolloServer<X>` can only be assigned to `ApolloServer<Y>`
when X and Y are the same. This is because:

- An `ApolloServer<{foo: number}>` is not a `ApolloServer<{}>`, because
  you can invoke `executeOperation` on the latter with an empty context
  object, which would confuse the former (this is the contravariance we
  already had).
- An `ApolloServer<{}>` is not a `ApolloServer<{foo: number}>`, because
  you can invoke `addPlugin` on the latter with a plugin whose methods
  expect to be called with a `contextValue` with `{foo: number}` on it,
  which isn't the case for the former.

Considering the second condition is why this is now invariant (`in
out`).  We're not quite sure why TS couldn't figure this out for us, but
it can't.

Second, we add `server: ApolloServer` to various plugin hook arguments
(`GraphQLRequestContext` and `GraphQLServerContext`). This makes
`logger` and `cache` on `GraphQLRequestContext` somewhat redundant, so
we make those fields into public readonly fields on `ApolloServer` and
remove them from the plugin hook arguments. (We thought this was related
to the other part because adding `server` appeared to require invariance
instead of contravariance, but it turns out that we needed invariance
anyway due to `addPlugin`.)

Note that this means that anyone consuming our `.d.ts` files must be on
TS4.7. Before v4.0.0 we'll probably fix that; see #6423.

Fixes #6264. Fixes #6082.
Copy link
Member

@trevor-scheer trevor-scheer left a comment

Choose a reason for hiding this comment

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

LGTM!

@glasser glasser merged commit 14239c6 into version-4 Jul 12, 2022
@glasser glasser deleted the glasser/invariance branch July 12, 2022 22:36
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants