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

Release 2.11.0 #3763

Merged
merged 37 commits into from
Mar 3, 2020
Merged

Release 2.11.0 #3763

merged 37 commits into from
Mar 3, 2020

Conversation

abernix
Copy link
Member

@abernix abernix commented Feb 6, 2020

As with release PRs in the past, this is a PR tracking a release-x.y.z branch for an upcoming release of Apollo Server. 🙌 The version in the title of this PR should correspond to the appropriate branch.

Check the appropriate milestone (to the right) for more details on what we hope to get into this release!

The intention of these release branches is to gather changes which are intended to land in a specific version (again, indiciated by the subject of this PR). Release branches allow additional clarity into what is being staged, provide a forum for comments from the community pertaining to the release's stability, and to facilitate the creation of pre-releases (e.g. alpha, beta, rc) without affecting the master branch.

PRs for new features might be opened against or re-targeted to this branch by the project maintainers. The master branch may be periodically merged into this branch up until the point in time that this branch is being prepared for release. Depending on the size of the release, this may be once it reaches RC (release candidate) stage with an -rc.x release suffix. Some less substantial releases may be short-lived and may never have pre-release versions.

When this version is officially released onto the latest npm tag, this PR will be merged into master.

@abernix abernix added this to the Release 2.11.0 milestone Feb 6, 2020
@abernix abernix changed the title As with [release PRs in the past](https://github.com/apollographql/apollo-server/labels/%F0%9F%8F%97%20release), this is a PR tracking a release-x.y.z branch for an upcoming release of Apollo Server. 🙌 The version in the title of this PR should correspond to the appropriate branch. Release 2.11.0 Feb 6, 2020
@abernix abernix added the 📦 release Applied to PRs which track upcoming releases. label Feb 6, 2020
Existing users who have NOT sub-classed `RemoteGraphQLDataSource` with their
own implementation of `didReceiveResponse` and have NOT similarly provided a
`didReceiveResponse` option to its constructor are unaffected by this change.

**All others must adjust their implementations of `didReceiveResponse`!**

This commit makes breaking changes to the existing expectations, signature
and behavior of the optionally overridden `didReceiveResponse` hook in the
`RemoteGraphQLDataSource` class.

This change is intended to better align the signature of `didReceiveResponse`
with similar life-cycle hooks on the `RemoteGraphQLDataSource`, such as the
`willSendRequest` method.  Furthermore, this change helps prepare for an
upcoming Apollo Gateway feature which allows it to operate in APQ (automated
persisted query) mode with downstream services.

Specifically, this commit changes `didReceiveResponse` in the following ways:

- **Will now receive [`GraphQLRequestContext`] as the only parameter.**

  Previously, it received three parameters: `res`, `req` and `context`, where
  `res` and `req` were the HTTP `Response` and `Request` respectively.  These
  values are still available on the `GraphQLRequestContext` object, though they
  are located on the `http` property (of each), as is the case in most
  other Apollo Server constructs.  Not only does this more consistently match
  the pattern received by `RemoteGraphQLDataSource`'s `willSendRequest` but it
  also matches the patterns from `ApolloServerPlugin`'s life-cycle hooks.

  See the referenced type definition for details on `GraphQLRequestContext`.

- **Sub-classes no longer needs to call base class methods.**

  Previously, it was either necessary to call `this.parseBody` or
  `super.didReceiveResponse` merely to parse the incoming response body into
  JSON and return it.  This is no longer necessary.  If you desire changing
  the parsing behavior, override the (already public) `parseBody` method
  appropriately.

- **It no longer has a default implementation**

  Previously, the `didReceiveResponse` method had baked-in response parsing in
  a way that made it more difficult to use the method for its primary purpose,
  which was to offer implementers the ability to lift transport-specific
  properties (e.g. headers) onto the overall request context.  For example,
  using a response header's value as a contributor to a header that eventually
  gets returned by the gateway.

  Because there is no longer an implementation, existing users no longer
  need to call `super.didReceiveResponse`.

- **TypeScript: The `TContext` is now the only type argument.**

  Previously, this method accepted two type arguments.  Now, it only
  requires a single type argument, the `TContext`.

[`GraphQLRequestContext`]: https://github.com/apollographql/apollo-server/blob/2562d096/packages/apollo-server-types/src/index.ts#L61-L65
* gateway: Allow use of APQ when querying downstream services.

This introduces support to Apollo Gateway which can leverage [Automated
Persisted Queries] (APQ) when communicating with downstream
implementing services in a federated architecture.

In an identical way as APQ saves bytes on the wire (read: network) in a
traditional handshake between a client and the server, this implements that behavior
in the internal communication between federated servers and the gateway that
fronts them.

This is accomplished by first attempting to utilizing a SHA-256 hex hash
(consistently, 32 bytes) of the operation which is destined for the
downstream server, rather than the complete, typically much larger query
itself.

In the event that the downstream server supports APQ (Apollo Server does by
default, unless it's been disabled), the downstream server will check its
APQ registry for the full operation body.  If it has it, it will use that
cached body to process the request and return the results.  If it does not
find the query in its existing registry, it will return a message to the
gateway that the query is not found in its registry, and the gateway will
re-transmit the request with the full operation payload.  On receipt of this
full query, the downstream server will cache the operation for future
requests (keyed by the SHA-256 hash), and return the expected result without
further delay.

This means that once a server has warmed up its APQ registry with repeated
operations, subsequent network chatter will be greatly reduced.
Furthermore, as noted in the attached documentation, the APQ registry can be
backed by a distributed store, such as Memcached or Redis, allowing multiple
downstream GraphQL servers to share the same cache, and persist it across
restarts.

By default, APQ behavior is disabled on `RemoteGraphQLDataSource`.  To
enable it, the `apq` property should be set to true.  Future versions of the
`RemoteGraphQLDataSource` could negotiate this capability on their own, but
this does not attempt to make that negotiation right now.

[Automated Persisted Queries]: https://www.apollographql.com/docs/apollo-server/performance/apq/

* tests: De-compose `toHaveFetched` in preparation for similar matchers.

* tests: Introduce `toHaveFetchNth` with to test critical order of fetches.

It's plausible that we should change every existing `toHaveFetch` to use
this matcher which enforces order.   Though it also seems plausible that
custom matchers aren't as flexible as they need to be in practice, since in
addition to the need to use Jest-built in methods (like the `nth`-call
matchers) there are other specific usages of this which are just surfacing
now (with APQ) that could be tested less precisely using
`expect.objectContaining()`, rather than testing concerns which are not
really necessary (like matching the hash).

If this matcher still supported partial matches then this would be possible.
However, since we're serializing the body into an `Request` before matching it
(which I'm not sure why we do and there is no comment to indicate why) this
isn't possible as Jest's matchers cannot survive that serialization.

* tests: Make `Matcher` declaration merges match new Jest definitions.

Without this change, every single usage of our `Matcher` is represented as a
type error since Jest has changed their own implementation of `Matcher` to
introduce a new generic type argument.

It's too bad that this didn't fail tests at the time that that Jest package
was updated!

* Re-jigger `RemoteGraphQLDataSource`'s `process` with new `sendRequest` method.

This introduces a new private `sendRequest` method that handles existing
behavior which existed within `RemoteGraphQLDataSource`'s `process`.

It should be a no-op change.

An upcoming commit will make multiple requests to downstream services in its
course of attempting APQ negotiation and this should facilitate that change
and avoid repetition of logic.
 - @apollo/federation@0.13.0-alpha.0
 - @apollo/gateway@0.13.0-alpha.0
abernix and others added 14 commits February 12, 2020 18:49
 - @apollo/federation@0.13.1-alpha.0
 - @apollo/gateway@0.13.1-alpha.0
For large queries (esp. ones that leverage many nested fragments),
queries to downstream services can blow up astronomically because
the gateway expands everything during a downstream request.

i.e. we've seen a ~700 line query become over 200k lines due to
this expansion.

This commit has the gateway build fragments on the fly for the
selection sets that it encounters and reuses them whenever possible.
This is an initial and simple implementation, but with tangible wins.

This is currently being landed as an experimental feature that is
disabled by default. To enable, simply add to your gateway config:
experimental_autoFragmentization: true
 - @apollo/gateway@0.13.2-alpha.0
* Introduce `make-fetch-happen` for GCS requests
* Implement in memory cache manager for make-fetch-happen
* Provide local typings for `make-fetch-happen`
* Skip node v6 tests for federation and gateway packages
…ble.

This doesn't comprehensively fix places where we use `console` but `logger`
isn't already in scope, but these are easy wins.

cc @trevor-scheer
abernix and others added 11 commits February 24, 2020 17:03
 - apollo-cache-control@0.9.0-alpha.1
 - apollo-datasource-rest@0.8.0-alpha.1
 - apollo-engine-reporting@1.7.0-alpha.1
 - @apollo/federation@0.13.2-alpha.1
 - @apollo/gateway@0.13.2-alpha.1
 - apollo-server-azure-functions@2.11.0-alpha.1
 - apollo-server-cloud-functions@2.11.0-alpha.1
 - apollo-server-cloudflare@2.11.0-alpha.1
 - apollo-server-core@2.11.0-alpha.1
 - apollo-server-errors@2.4.0-alpha.1
 - apollo-server-express@2.11.0-alpha.1
 - apollo-server-fastify@2.11.0-alpha.1
 - apollo-server-hapi@2.11.0-alpha.1
 - apollo-server-integration-testsuite@2.11.0-alpha.1
 - apollo-server-koa@2.11.0-alpha.1
 - apollo-server-lambda@2.11.0-alpha.1
 - apollo-server-micro@2.11.0-alpha.1
 - apollo-server-plugin-base@0.7.0-alpha.1
 - apollo-server-plugin-response-cache@0.4.0-alpha.1
 - apollo-server-testing@2.11.0-alpha.1
 - apollo-server-types@0.3.0-alpha.1
 - apollo-server@2.11.0-alpha.1
 - apollo-tracing@0.9.0-alpha.1
 - graphql-extensions@0.11.0-alpha.1
These types are compatible, but this change is necessary to account for the
fact that, while we have provided types for `make-fetch-happen` which matter
during development of Apollo Server, we don't include those types in the
distribution.  We could do that, of course, but as I'll note in a minute, we
want something more generic anyhow.

The omission of the types in the published package (currently, before this
commit) results in typing errors for consumers of `@apollo/gateway` since
the `import` statement for the `Fetcher` type from `make-fetch-happen` is
still emitted (see attached [[Screenshot]]).

Switching to the type that `apollo-serve-env` already provides via its
`fetch` implementation (literally, `typeof fetch`) should be a no-op change
and actually provide the more generic compatibility we want for those who
want to bring-their-own-fetch.  This should be the same as any type provided
by other Fetch-compatible packages as well, including `isomorphic-fetch`,
etc.

[Screenshot]: https://cc.jro.cc/E0uqEXrX
 - @apollo/federation@0.13.2-alpha.2
 - @apollo/gateway@0.13.2-alpha.2
 - apollo-server-azure-functions@2.11.0-alpha.2
 - apollo-server-cloud-functions@2.11.0-alpha.2
 - apollo-server-cloudflare@2.11.0-alpha.2
 - apollo-server-core@2.11.0-alpha.2
 - apollo-server-express@2.11.0-alpha.2
 - apollo-server-fastify@2.11.0-alpha.2
 - apollo-server-hapi@2.11.0-alpha.2
 - apollo-server-integration-testsuite@2.11.0-alpha.2
 - apollo-server-koa@2.11.0-alpha.2
 - apollo-server-lambda@2.11.0-alpha.2
 - apollo-server-micro@2.11.0-alpha.2
 - apollo-server-testing@2.11.0-alpha.2
 - apollo-server@2.11.0-alpha.2
...except in a different place.

cc @trevor-scheer
 - @apollo/federation@0.13.2-alpha.3
 - @apollo/gateway@0.13.2-alpha.3
 - apollo-server-azure-functions@2.11.0-alpha.3
 - apollo-server-cloud-functions@2.11.0-alpha.3
 - apollo-server-cloudflare@2.11.0-alpha.3
 - apollo-server-core@2.11.0-alpha.3
 - apollo-server-express@2.11.0-alpha.3
 - apollo-server-fastify@2.11.0-alpha.3
 - apollo-server-hapi@2.11.0-alpha.3
 - apollo-server-integration-testsuite@2.11.0-alpha.3
 - apollo-server-koa@2.11.0-alpha.3
 - apollo-server-lambda@2.11.0-alpha.3
 - apollo-server-micro@2.11.0-alpha.3
 - apollo-server-testing@2.11.0-alpha.3
 - apollo-server@2.11.0-alpha.3
* Centralize mocking fixtures and reuse them
* Simplify mock request signatures for more easily read and written tests
* Create nock/nockSuccess pairs for the most common use case and flexibility

cc @abernix
@abernix abernix merged commit 491c80d into master Mar 3, 2020
abernix added a commit to apollographql/federation that referenced this pull request Sep 4, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
📦 release Applied to PRs which track upcoming releases.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants