Skip to content

Releases: apollographql/router

v1.0.0

22 Sep 13:09
e81b96b
Compare
Choose a tag to compare

Note

🤸 We've reached our initial v1.0.0 release. This project adheres to Semantic Versioning v2.0.0 and our version numbers follow the practices outlined in that specification. If you're updating from 1.0.0-rc.2 there is one breaking change to the API that is unlikely to affect you.

The migration steps from each pre-1.0 version will vary depending on which release you're coming from. To update from previous versions, you can consult the Release Notes for whichever version you are running and work your way to v1.0.0.

Our documentation has been updated to match our current v1.x state. In general, if you run the Router with your existing configuration, you should receive output indicating any values which are no longer valid and find their v1.0.0 equivalent in the updated documentation, or by searching the CHANGELOG.md for the prior configuration option to find when it changed.

Lastly, thank you for all of your positive and constructive feedback in our pre-1.0 stages. If you encounter any questions or feedback while updating to v1.0.0, please search for or open a GitHub Discussion or file a GitHub Issue if you find something working differently than it's documented.

We're excited about the path ahead! 👐

❗ BREAKING ❗

Removed Request::from_bytes() from public API (Issue #1855)

We've removed Request::from_bytes() from the public API. We were no longer using it internally and we hardly expect anyone external to have been relying on it so it was worth the remaining breaking change prior to v1.0.0.

We discovered this function during an exercise of documenting our entire public API. While we considered keeping it, it didn't necessarily meet our requirements for shipping it in the public API. It's internal usage was removed in [d147f97d](d147f97d as part of PR #429.

We're happy to consider re-introducing this in the future (it even has a matching Response::from_bytes() which it composes against nicely!), but we thought it was best to remove it for the time-being.

By @abernix in #1858

🚀 Features

Reintroduce health check (Issue #1861)

We have re-introduced a health check at the /health endpoint on a dedicated port that is not exposed on the default GraphQL execution port (4000) but instead on port 8088. We recommend updating from the previous health-point suggestion by consulting our health check configuration documentation. This health check endpoint will act as an "overall" health check for the Router and we intend to add separate "liveliness" and "readiness" checks on their own dedicated endpoints (e.g., /health/live and /health/ready) in the future. At that time, this root /health check will aggregate all other health checks to provide an overall health status however, today, it is simply a "liveliness" check and we have not defined "readiness". We also intend to use port 8088 for other ("internal") functionality in the future, keeping the GraphQL execution endpoint dedicated to serving external client requests.

As for some additional context as to why we've brought it back so quickly: We had previously removed the health check we had been offering in PR #1766 because we wanted to do some additional configurationd design and lean into a new "admin port" (8088). As a temporary solution, we offered the instruction to send a GET query to the Router with a GraphQL query. After some new learnings and feedback, we've had to re-visit that conversation earlier than we expected!

Due to default CSRF protections enabled in the Router, GET requests need to be accompanied by certain HTTP headers in order to disqualify them as being CORS-preflightable requests. While sending the additional header was reasonable straightforward in Kubernetes, other environments (including Google Kubernetes Engine's managed load balancers) didn't offer the ability to send those necessary HTTP headers along with their GET queries. So, the /health endpoint is back.

The health check endpoint is now exposed on 127.0.0.1:8088/health by default, and its listen socket address can be changed in the YAML configuration:

health-check:
  listen: 127.0.0.1:8088 # default
  enabled: true # default

The previous health-check suggestion (i.e., GET /?query={__typename}) will still work, so long as your infrastructure supports sending custom HTTP headers with HTTP requests. Again though, we recommend updating to the new health check.

By @o0Ignition0o and @BrynCooke in #1859

🐛 Fixes

Remove apollo_private and OpenTelemetry entries from logs (Issue #1862)

This change removes some apollo_private and OpenTelemetry (e.g., otel.kind) fields from the logs.

By @garypen and @bnjjj in #1868

Update and validate Dockerfile files (Issue #1854)

Several of the Dockerfiles in the repository were out-of-date with respect to recent configuration changes. We've updated the configuration files and extended our tests to catch this automatically in the future.

By @garypen in #1857

🛠 Maintenance

Disable Deno snapshotting when building inside docs.rs

This works around V8 linking errors and caters to specific build-environment constraints and requirements that exist on the Rust documentation site docs.rs.

By @SimonSapin in #1847

Add the Studio Uplink schema to the repository, with a test checking that it is up to date.

Previously we were downloading the Apollo Studio Uplink schema (which is used for fetching Managed Federation schema updates) at compile-time, which would fail in build environments without Internet access, like docs.rs' build system.

If an update is needed, the test failure will print a message with the command to run.

By @SimonSapin in #1847

v1.0.0-rc.2

20 Sep 14:13
f4e5263
Compare
Choose a tag to compare

Note
There are no breaking changes in this release! Thank you for the constructive and positive feedback and validation as well as the contributions from our external contributors. We look forward to seeing you at v1.0.0 soon!

🐛 Fixes

Update apollo-parser to v0.2.11 (PR #1841)

Fixes error creation for missing selection sets in named operation definitions by updating to apollo-rs's apollo-parser v0.2.11.

By @lrlna in #1841

Fix router scaffold version (Issue #1836)

Add v prefix to the package version emitted in our scaffold tooling when a published version of the crate is available. This results in packages depending (appropriately, we would claim!) on our published Cargo crates, rather than Git references to the repository.

By @bnjjj in #1838

Fixed extraVolumeMounts in Helm charts (Issue #1824)

Correct a case in our Helm charts where extraVolumeMounts was not be being filled into the deployment template correctly.

By @LockedThread in #1831

Do not fill in a skeleton object when canceling a subgraph request (Issue #1819)

Given a supergraph with multiple subgraphs USER and ORGA, like this example supergraph, if a query spans multiple subgraphs, like this:

query {
  currentUser { # USER subgraph
    activeOrganization { # ORGA subgraph
      id
      creatorUser {
        name
      }
    }
  }
}

...when the USER subgraph returns {"currentUser": { "activeOrganization": null }}, then the request to the ORGA subgraph
should be cancelled and no data should be generated. This was not occurring since the query planner was incorrectly creating an object at the target path. This is now corrected.

This fix also improves the internal usage of mocked subgraphs with TestHarness.

By @Geal in #1819

Default conditional @defer condition to true (Issue #1820)

According to recent updates in the @defer specification, defer conditions must default to true. This corrects a bug where that default value wasn't being initialized properly.

By @o0Ignition0o in #1832

Support query plans with empty primary subselections (Issue #1778)

When a query with @defer would result in an empty primary response, the router was returning
an error in interpreting the query plan. It is now using the query plan properly, and detects
more precisely queries containing @defer.

By @Geal in #1778

🛠 Maintenance

Add more compilation gates to hide noisy warnings (PR #1830)

Add more gates (for the console feature introduced in PR #1632) to not emit compiler warnings when using the --all-features flag. (See original PR for more details on the flag usage.)

By @bnjjj in #1830

Deny panic, unwrap and expect in the spec module (Issue #1844)

We are generally working to eliminate unwrap() and expect() statements from critical paths in the codebase and have done so on the spec module. The spec module, in particular, is reached after parsing has occurred so any invariants expressed by these expects would have already been enforced or validated. Still, we've decided to tighten things even further, by raising errors instead to provide end-users with even more stability.

To further defend against re-introduction, the spec module now has linting annotations that prevent its content from using any code that explicitly panics.

#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::panic)]

By @o0Ignition0o in #1844

Remove potential panics from query plan execution (PR #1842)

Some remaining parts of the query plan execution code were using expect(), unwrap() and panic() to guard against assumptions
about data. These conditions have been replaced with errors which will returned in the response preventing the possibility of panics in these code paths.

By @Geal in #1842

v1.0.0-rc.1

16 Sep 14:22
f3f27d7
Compare
Choose a tag to compare

Note
We're almost to 1.0! We've got a couple relatively small breaking changes to the configuration for this release (none to the API) that should be relatively easy to adapt to and a number of bug fixes and usability improvements.

❗ BREAKING ❗

Change headers propagation configuration (PR #1795)

While it wasn't necessary today, we want to avoid a necessary breaking change in the future by proactively making room for up-and-coming work. We've therefore introduced another level into the headers configuration with a request object, to allow for a response (see Issue #1284) to be an additive feature after 1.0.

A rough look at this should just be a matter of adding in request and indenting everything that was inside it:

headers:
    all:
+     request:
          - remove:
              named: "test"

The good news is that we'll have response in the future! For a full set of examples, please see the header propagation documentation.

By @bnjjj in #1795

Bind the Sandbox on the same endpoint as the Supergraph, again (Issue #1785)

We have rolled back an addition that we released in this week's v1.0.0-rc.0 which allowed Sandbox (an HTML page that makes requests to the supergraph endpoint) to be on a custom socket. In retrospect, we believe it was premature to make this change without considering the broader impact of this change which ultimately touches on CORS and some developer experiences bits. Practically speaking, we may not want to introduce this because it complicates the model in a number of ways.

For the foreseeable future, Sandbox will continue to be on the same listener address as the supergraph listener.

It's unlikely anyone has really leaned into this much already, but if you've already re-configured sandbox or homepage to be on a custom listen-er and/or path in 1.0.0-rc.0, here is a diff of what you should remove:

sandbox:
-  listen: 127.0.0.1:4000
-  path: /
  enabled: false
homepage:
-  listen: 127.0.0.1:4000
-  path: /
  enabled: true

Note this means you can either enable the homepage, or the sandbox, but not both.

By @o0Ignition0o in #1796

🚀 Features

Automatically check "Return Query Plans from Router" checkbox in Sandbox (Issue #1803)

When loading Sandbox, we now automatically configure it to toggle the "Request query plans from Router" checkbox to the enabled position which requests query plans from the Apollo Router when executing operations. These query plans are displayed in the Sandbox interface and can be seen by selecting "Query Plan Preview" from the drop-down above the panel on the right side of the interface.

By @abernix in #1804

🐛 Fixes

Fix --dev mode when no configuration file is specified (Issue #1801) (Issue #1802)

We've reconciled an issue where the --dev mode flag was being ignored when running the router without a configuration file. (While many use cases do require a configuration file, the Router actually doesn't need a confguration in many cases!)

By @bnjjj in #1808

Respect supergraph's path for Kubernetes deployment probes (Issue #1787)

If you've configured the supergraph's path property using the Helm chart, the liveness
and readiness probes now utilize these correctly. This fixes a bug where they continued to use the default path of / and resulted in a startup failure.

By @damienpontifex in #1788

Get variable default values from the query for query plan condition nodes (PR #1640)

The query plan condition nodes, generated by the if argument of the @defer directive, were
not using the default value of the variable passed in as an argument.

This also fixes default value validations for non-@defer'd queries.

By @Geal in #1640

Correctly hot-reload when changing the supergraph's listen socket (Issue #1814)

If you change the supergraph's listen socket while in --hot-reload mode, the Router will now correctly pickup the change and bind to the new socket.

By @o0Ignition0o in #1815

🛠 Maintenance

Improve error message when querying non existent field Issue #1816

When querying a non-existent field you will get a better error message:

{
  "errors": [
    {
-       "message": "invalid type error, expected another type than 'Named type Computer'"
+       "message": "Cannot query field \"xxx\" on type \"Computer\""
    }
  ]
}

By @bnjjj in #1817

Update apollo-router-scaffold to use the published apollo-router crate PR #1782

Now that apollo-router is released on crates.io, we have updated the project scaffold to rely on the published crate instead of Git tags.

By @o0Ignition0o in #1782

Refactor Configuration validation Issue #1791

Instantiating Configurations is now fallible, because it will run consistency checks on top of the already run structure checks.

By @o0Ignition0o in #1794

Refactor response-formatting tests #1798

Rewrite the response-formatting tests to use a builder pattern instead of macros and move the tests to a separate file.

By @Geal in #1798

📚 Documentation

Add rustdoc documentation to various modules (Issue #799)

Adds documentation for:

  • apollo-router/src/layers/instrument.rs
  • apollo-router/src/layers/map_first_graphql_response.rs
  • apollo-router/src/layers/map_future_with_request_data.rs
  • apollo-router/src/layers/sync_checkpoint.rs
  • apollo-router/src/plugin/serde.rs
  • apollo-router/src/tracer.rs

By @garypen in #1792

Fixed docs.rs publishing error from our last release

During our last release we discovered for the first time that our documentation wasn't able to compile on the docs.rs website, leaving our documentation in a failed state.

While we've reconciled that particular problem, we're now being affected by this internal compiler errors (ICE) that is affecting anyone using 1.65.0-nightly builds circa today. Since docs.rs uses nightly for all builds, this means it'll be a few more days before we're published there.

With thanks to @SimonSapin in apollographql/federation-rs#185

v1.0.0-rc.0

14 Sep 16:02
c214edf
Compare
Choose a tag to compare

Note

👋 We're at our release candidate stage but we still have a round of breaking changes and features in this release. Not much more after this! Those using the apollo-router as a library should be minimally impacted by Rust API changes in this 1.0.0-rc.0 release, however there are notable changes to the configuration file and default values outlined below. We hope you'll appreciate the changes (including the secure defaults, flexibility and introduction of a --dev mode). Thanks for your continued feedback and cooperation and please try out this release candidate! We will graduate to 1.0 as soon as possible! ✨

❗ BREAKING ❗

Note

We are entering our release candidate ("RC") stage and expect this to be the last of our breaking changes. Overall, most of the breaking changes in this release revolve around three key factors which were motivators for most of the changes:

  1. Having safe and security defaults which are suitable for production
  2. Polishing our YAML configuration ergonomics and patterns
  3. The introduction of a development mode activated with the --dev flag

See the full changelog below for details on these (including the "Features" section for the --dev changes!)

Adjusted socket ("listener") addresses for more secure default behaviors

  • The Router will not listen on "all interfaces" in its default configuration (i.e., by binding to 0.0.0.0). You may specify a specific socket by specifying the interface:port combination. If you desire behavior which binds to all interfaces, your configuration can specify a socket of 0.0.0.0:4000 (for port 4000 on all interfaces).
  • By default, Prometheus (if enabled) no longer listens on the same socket as the GraphQL socket. You can change this behavior by binding it to the same socket as your GraphQL socket in your configuration.
  • The health check endpoint is no longer available on the same socket as the GraphQL endpoint (In fact, the health check suggestion has changed in ways that are described elsewhere in this release's notes. Please review them separately!)

Safer out-of-the box defaults with sandbox and introspection disabled (PR #1748)

To reflect the fact that it is not recomended to have introspection on in production (and since Sandbox uses introspection to power its development features) the sandbox and introspection configuration are now disabled unless you are running the Router with --dev.

If you would like to force them on even when outside of --dev mode, you can set them to true explicitly in your YAML configuration:

sandbox:
  enabled: true
supergraph:
  introspection: true

By @bnjjj in #1748

Landing page ("home page") replaces Sandbox in default "production" mode (PR #1768)

As an extension of Sandbox and Introspection being disabled by default (see above), the Router now displays a simple landing page when running in its default mode. When you run the Apollo Router with the new --dev flag (see "Features" section below) you will still see the existing "Apollo Studio Sandbox" experience.

We will offer additional options to customize the landing page in the future but for now you can disable the homepage entirely (leaving a very generic page with a GraphQL message) by disabling the homepage entirely in your configuration:

homepage:
  enabled: false

By @o0Ignition0o in #1768

Listeners, paths and paths can be configured individually (Issue #1500)

It is now possible to individually configure the following features' socket/listener addresses (i.e., the IP address and port) in addition to the URL path:

  • GraphQL execution (default: http://127.0.0.1:4000/)
  • Sandbox (default when using --dev: http://127.0.0.1:4000/)
  • Prometheus (default when enabled: http://127.0.0.1:9090/metrics)

Examples of how to configure these can be seen in the YAML configuration overhaul section of this changelog (just below) as well as in our documentation.

By @o0Ignition0o in #1718

Overhaul/reorganization of YAML configuration (#1500)

To facilitate the changes in the previous bullet-points, we have moved configuration parameters which previously lived in the server section to new homes in the configuration, including listen, graphql_path, landing_page, and introspection. Additionally, preview_defer_support has moved, but is on by default and no longer necessary to be set explicitly unless you wish to disable it.

As another section (below) notes, we have removed the health check and instead recommend users to configure their health checks (in, e.g, Kubernetes, Docker, etc.) to use a simple GraphQL query: /?query={__typename}. Read more about that in the other section, however this is reflected by its removal in the configuration.

To exemplify the changes, this previous configuration will turn into the configuration that follows it:

Before

server:
  listen: 127.0.0.1:4000
  graphql_path: /graphql
  health_check_path: /health # Health check has been deprecated.  See below.
  introspection: false
  preview_defer_support: true
  landing_page: true
telemetry:
  metrics:
    prometheus:
      enabled: true

After

# This section is just for Sandbox configuration
sandbox:
  listen: 127.0.0.1:4000
  path: /
  enabled: false # Disabled by default, but on with `--dev`.

# This section represents general supergraph GraphQL execution
supergraph:
  listen: 127.0.0.1:4000
  path: /
  introspection: false
  # Can be removed unless it needs to be set to `false`.
  preview_defer_support: true

# The health check has been removed.  See the section below in the CHANGELOG
# for more information on how to configure health checks going forward.

# Prometheus scraper endpoint configuration
# The `listen` and `path` are not necessary if `127.0.0.1:9090/metrics` is okay
telemetry:
  metrics:
    prometheus:
      listen: 127.0.0.1:9090
      path: /metrics
      enabled: true

By @o0Ignition0o in #1718

Environment variable expansion adjustments (#1759)

  • Environment expansions must be prefixed with env..

  • File expansions must be prefixed with file..

  • The "default" designator token changes from : to :-. For example:

    ${env.USER_NAME:Nandor} => ${env.USER_NAME:-Nandor}

  • Failed expansions now result in an error

    Previously expansions that failed due to missing environment variables were silently skipped. Now they result in a configuration error. Add a default value using the above syntax if optional expansion is needed.

By @BrynCooke in #1763

Dedicated health check endpoint removed with new recommendation to use /query={__typename} query (Issue #1765)

We have removed the dedicated health check endpoint and now recommend users to configure their health checks (in, e.g, Kubernetes, Docker) to use a simple GraphQL query instead.

Use the following query with a content-type: application/json header as a health check instead of /.well-known/apollo/server-health:

/?query={__typename}

The Kubernetes documentation and related Helm charts have been updated to reflect this change.

Using this query has the added benefit of actually testing GraphQL. If this query returns with an HTTP 200 OK, it is just as reliable (and even more meaningful) than the previous /.well-known/apollo/server-health endpoint. It's important to include the content-type: application/json header to satisfy the Router's secure requirements that offer CSRF protections.

In the future, we will likely reintroduce a dedicated health check "liveliness" endpoint along with a meaningful "readiness" health check at the same time. In the meantime, the query above is technically more durable than the health check we offered previously.

By @abernix in https://github.com/apollographql/router/pull/TODO

Promote include_subgraph_errors out of "experimental" status (Issue #1773)

The include_subraph_errors plugin has been promoted out of "experimental" and will require a small configuration changes. For example:

-plugins:
-  experimental.include_subgraph_errors:
-    all: true # Propagate errors from all subraphs
-    subgraphs:
-      products: false # Do not propagate errors from the products subgraph
+include_subgraph_errors:
+  all: true # Propagate errors from all subraphs
+  subgraphs:
+    products: false # Do not propagate errors from the products subgraph

By @garypen in #1776

apollo-spaceport and uplink are now part of apollo-router (Issue #491)

Instead of being dependencies, they are now part of the apollo-router crate. They were not meant to be used independently.

By @SimonSapin in #1751

Remove over-exposed functions from the public API (PR #1746)

The following functions are only required for router implementation, so removing from external API:

subgraph::new_from_response
supergraph::n...
Read more

v1.0.0-alpha.3

07 Sep 15:59
84d3b8d
Compare
Choose a tag to compare

👋 We're getting closer to our release candidate stages so there are far less breaking changes to the API in these versions, rather changes to configuration. We'll have a bit more in the next releases, but nothing as bad as the bumps from pre-v1.0.0-alpha.x versions. Thanks for your feedback and cooperation! ✨

❗ BREAKING ❗

Unified supergraph and execution response types (PR #1708)

apollo_router::services::supergraph::Response and apollo_router::services::execution::Response were two structs with identical fields and almost-identical methods. The main difference was that builders were fallible for the former but not the latter.

They are now the same type (with one location a type alias of the other), with fallible builders. Callers may need to add either a operator ? (in plugins) or an .unwrap() call (in tests).

 let response = execution::Response::builder()
     .error(error)
     .status_code(StatusCode::BAD_REQUEST)
     .context(req.context)
-    .build();
+    .build()?;

By @SimonSapin in #1708

Rename originating_request to supergraph_request on various plugin Request structures (Issue #1713)

We feel that supergraph_request makes it more clear that this is the request received from the client.

By @garypen in #1715

Prometheus is no longer defaulting to the GraphQL endpoint and listener address (Issue #1645)

The Router's Prometheus interface is now exposed at 127.0.0.1:9090/metrics, rather than http://0.0.0.0:4000/plugins/apollo.telemetry/prometheus. This should be both more secure and also more generally compatible with the default settings that Prometheus expects (which also uses port 9090 and just /metrics as its defaults).

To expose to a non-localhost interface, it is necessary to explicitly opt-into binding to a socket address of 0.0.0.0:9090 (i.e., all interfaces on port 9090) or a specific available interface (e.g., 192.168.4.1) on the host.

Have a look at the Features section (below) to learn how to customize the listen address and the path.

By @o0Ignition0o in #1654

🚀 Features

New plugin helper: map_first_graphql_response (Issue #1564)

In supergraph and execution services, the service response contains not just one GraphQL response but a stream of them, in order to support features such as @defer.

This new method of ServiceExt and ServiceBuilderExt in apollo_router::layers wraps a service and calls a callback when the first GraphQL response in the stream returned by the inner service becomes available. The callback can then access the HTTP parts (headers, status code, etc) or the first GraphQL response before returning them.

See the doc-comments in apollo-router/src/layers/mod.rs for more.

By @SimonSapin in #1708

Users can customize the Prometheus listener address and URL path (Issue #1645)

You can now customize the Prometheus listener socket address and URL path in your YAML configuration:

telemetry:
  metrics:
    prometheus:
      listen: 127.0.0.1:9090 # default
      path: /metrics # default
      enabled: true

By @o0Ignition0o in #1654

Add an apollo_router::graphql::ResponseStream type alias (PR #1697)

It is equivalent to BoxStream<'static, graphql::Response> and makes
some type signatures slightly simpler.

By @SimonSapin in #1697

🐛 Fixes

Fix metrics duration for router request (#1705)

With the introduction of BoxStream for @defer we introduced a bug when computing HTTP request duration metrics where we failed to wait for the first response in the BoxStream.

By @bnjjj in #1705

Numerous fixes to preview @defer query planning (Issue #1698)

Updated to Federation 2.1.2-alpha.0 which brings in a number of fixes for the preview @defer support. These fixes include:

By @abernix in #1711

v1.0.0-alpha.2

06 Sep 16:47
0551832
Compare
Choose a tag to compare

👋 We're getting closer to our release candidate stages so there are far less breaking changes to the API in these versions, rather changes to configuration. We'll have a bit more in the next releases, but nothing as bad as the bumps from 0.15.x, through 0.16.0 and on to v1.0.0-alpha.0. Thanks for your feedback and cooperation! ✨

🚀 Features

Add service_name and service_namespace in telemetry.metrics.common (Issue #1490)

Add service_name and service_namespace in telemetry.metrics.common to reflect the same configuration than tracing.

telemetry:
  metrics:
    common:
      # (Optional, default to "apollo-router") Set the service name to easily find metrics related to the apollo-router in your metrics dashboards
      service_name: "apollo-router"
      # (Optional)
      service_namespace: "apollo"

By @bnjjj in #1492

🐛 Fixes

Fix distributed tracing header propagation (#1701)

Span context is now correctly propagated if you're trying to propagate tracing context to the router.

By @bnjjj in #1701

🛠 Maintenance

Replace startup crate with ctor crate (#1704)

At startup, the router registers plugins. The crate we used to use (startup) has been yanked from crates.io and archived on GitHub. We're unsure why the package was yanked, but we've decided to move to the ctor crate, which is more widely adopted and maintained.

This should fix the sudden errors for those who were using the router as a library or attempting to scaffold a new plugin using cargo scaffold.

By @garypen in #1704

macOS: Update Xcode build version from 11.7 to 13.4 (PR #1702)

We now build our macOS binaries with Xcode 13.4 rather than 11.7. This may result in the Router not working on very old versions of macOS but we'd rather get this out of the way before CircleCI potentially deprecates 11.x images themselves and we're unable to test on them anymore.

By @abernix in #1702

v1.0.0-alpha.1

02 Sep 13:48
b79d915
Compare
Choose a tag to compare

👋 We're getting closer to our release candidate stages so there are far less breaking changes to the API in this version, rather changes to configuration. We'll have a bit more in the next release, but nothing as bad as the bumps from 0.15.x, through 0.16.0 and on to v1.0.0-alpha.0

❗ BREAKING ❗

Preserve plugin response Vary headers (PR #1660)

It is now possible to set a Vary header in a client response from a plugin.

Note: This is a breaking change because the prior behaviour provided three default Vary headers and we've had to drop those to enable this change. If, after all plugin processing, there is no Vary header, the router will add one with a value of "origin", as is best-practice for cache control headers with CORS.

By @garypen in #1660

Fix the supported defer specification version to 20220824 (PR #1652)

Since the router will ship before the @defer specification is done, we add a parameter to the Accept and Content-Type headers to indicate which specification version is accepted.

The specification is fixed to graphql/graphql-spec@01d7b98

The router will now return a response with the status code 406 Not Acceptable if the Accept header does not match.

By @Geal in #1652

Change default enablement and promote experimental_defer_support to preview_defer_support (PR #1673)

Following up on a tremendous amount of work tracked in #80 - which brought various stages of @defer support to the Router - this changes our designation of its status from "Experimental" to "Preview". It's worth noting that the @defer specification has just graduated to "Stage 2 (Draft)" mode in the GraphQL Working Group, so changes may still be expected and there are two stages ahead. To help things progress:

  • We've lifted the previous requirement that users opt into defer support by setting experimental_defer_support: true in the server section of their configuration. It is now on by default.

  • The option is now called preview_defer_support and it can be set to false to specifically opt out of it existing at all. This might be desired if you would prefer that it not even show up in introspection or be possible to use even if a client requests it.

  • Using @defer support requires clients set the appropriate HTTP accept header to use it. This puts the burden of understanding the risks of an early-preview on the clients who will need to consume the Router's responses. This is particularly important for clients who have long-lived support requirements (like native mobile apps).

    To see which headers are required, see #1648.

By @abernix in #1685

🚀 Features

Return an error when nullifying a non-null field (Issue #1304)

Nullability rules may remove parts of the response without indicating why. Error messages now indicate which part of the response triggered nullability rules.

By @Geal in #1537

router now provides TraceId (PR #1663)

If you need a reliable way to link together the various stages of pipeline processing, you can now use

apollo_router::tracer::TraceId::new()

By @garypen in #1663

🐛 Fixes

Docker images: Use absolute path for ENTRYPOINT (PR #1684)

This restores the absolute path in ENTRYPOINT in our Dockerfiles (and published images) to allow users to change their working directory without consequence (and without needing to change it back to /dist or override the entrypoint).

By @110y in #1684

Update our helm documentation to illustrate how to use our registry (#1643)

Updated documentation for helm charts to point to Apollo OCI registry.

By @garypen in #1649

Update router-bridge to query-planner v2.1.1 (PR #1650 PR #1672)

The 2.1.0 release of the query planner comes with fixes to fragment interpretation and reduced memory usage.
The 2.1.1 release of the query planner fixes an issue with the @defer directive's if argument being ignored.

By @Geal in #1650 and #1672

Do not nullify the entire query if the root operation is not present (PR #1674)

If a root field was not returned by the subgraph (e.g., when there's an error) the entire data object should not be nullified. Instead, the root field that should be null (unless it is non nullable).

By @Geal in #1674

Propagate graphql response regardless of the subgraph HTTP status code. (#1664)

Subgraph service calls no longer return an error when the received HTTP status code isn't 200. The GraphQL specification does not specify HTTP status code behavior since the GraphQL specification is transport agnostic.

This commit removes our HTTP status code check in the subgraph_service.

By @o0Ignition0o in #1664

🛠 Maintenance

Remove cache layer (PR #1647)

ServiceBuilderExt::cache was removed in v0.16.0. The unused CacheLayer has now also been removed.

By @garypen in #1647

Refactor SupergraphService (PR #1615)

The SupergraphService code became too complex, so much that rustfmt could not modify it anymore.
This breaks up the code in more manageable functions.

By @Geal in #1615

Conditionally use HorizontalPodAutoscaler api version autoscaling/v2 (PR #1635)

The helm chart HorizontalPodAutoscaler resource now will use API version autoscaling/v2 on Kubernetes hosts greater than 1.23 when the version is available. Fallback to version autoscaling/v2beta1 will still be utilised when this version is unavailable

By @damienpontifex in #1635

v1.0.0-alpha.0

29 Aug 12:48
d5e6406
Compare
Choose a tag to compare

❗ BREAKING ❗

Move cors configuration from server to root-level (PR #1586)

The cors configuration is now located at the root-level of the configuration file, rather than inside server.

For example:

- server:
-   cors:
-     origins:
-       - https://yourdomain.com
+ cors:
+   origins:
+     - https://yourdomain.com

By @garypen in #1586

Exit the router after logging panic details (PR #1602)

The Router will now terminate in the (unlikely) case where it panics.

By @garypen in #1602

Rename the endpoint parameter to graphql_path (#1606)

The endpoint parameter within the server portion of the YAML configuration has been renamed to graphql_path to more accurately reflect its behavior.

If you used this option, the necessary change would look like:

- server:
-   endpoint: /graphql
+ server:
+   graphql_path: /graphql

By @abernix in #1609

Remove activate() from the plugin API (PR #1569)

Recent changes to configuration reloading means that the only known consumer of this API, telemetry, is no longer using it.

Let's remove it since it's simple to add back if later required.

By @garypen in #1569

Rename TestHarness methods (PR #1579)

Some methods of apollo_router::TestHarness were renamed:

  • extra_supergraph_pluginsupergraph_hook
  • extra_execution_pluginexecution_hook
  • extra_subgraph_pluginsubgraph_hook

By @SimonSapin in #1579

Request and Response types from apollo_router::http_ext are private (Issue #1589)

These types were wrappers around the Request and Response types from the http crate.
Now the latter are used directly instead.

By @SimonSapin in #1589

Changes to IntoHeaderName and IntoHeaderValue (PR #1607)

Note: These types are typically not used directly, so we expect most user code to require no changes.

  • Move from apollo_router::http_ext to apollo_router::services
  • Rename to TryIntoHeaderName and TryIntoHeaderValue
  • Make contents opaque
  • Replace generic From<T: Display> conversion with multiple specific conversions
    that are implemented by http::headers::Header{Name,Value}.

By @SimonSapin in #1607

QueryPlan::usage_reporting and QueryPlannerContent are private (Issue #1556)

These items have been removed from the public API of apollo_router::services::execution.

By @SimonSapin in #1568

Insert the full target triplet in the package name, and prefix with v (Issue #1385)

The release tarballs now contain the full target triplet in their name along with a v prefix to be consistent with our other packaging techniques (e.g., Rover).

For example:

  • router-0.16.0-x86_64-linux.tar.gz becomes router-v0.16.0-x86_64-unknown-linux-gnu.tar.gz
  • router-0.16.0-x86_64-macos.tar.gz becomes router-v0.16.0-x86_64-apple-darwin.tar.gz
  • router-0.16.0-x86_64-windows.tar.gz becomes router-v0.16.0-x86_64-pc-windows-msvc.tar.gz

By @abernix and @Geal in #1433 (which re-lands work done in #1393)

Many structs and enums are now #[non_exhaustive] (Issue #1550)

This means we may adjust struct fields or enum variants in additive ways in the future without breaking changes. To prepare for that eventuality:

  1. When using a struct pattern (such as for deconstructing a value into its fields),
    use .. to allow further fields:
-let PluginInit { config, supergraph_sdl } = init;
+let PluginInit { config, supergraph_sdl, .. } = init;
  1. Use field access instead:
-let PluginInit { config, supergraph_sdl } = init;
+let config = init.config;
+let supergraph_sdl = init.supergraph_sdl;
  1. When constructing a struct, use a builder or constructor method instead of struct literal syntax:
-let error = graphql::Error {
-    message: "something went wrong".to_string(),
-    ..Default::default()
-};
+let error = graphql::Error::builder()
+    .message("something went wrong")
+    .build();
  1. When matching on an enum, add a wildcard match arm:
match error {
    ApolloRouterError::StartupError => "StartupError",
    ApolloRouterError::HttpServerLifecycleError => "HttpServerLifecycleError",
    ApolloRouterError::NoConfiguration => "NoConfiguration",
    ApolloRouterError::NoSchema => "NoSchema",
    ApolloRouterError::ServiceCreationError(_) => "ServiceCreationError",
    ApolloRouterError::ServerCreationError(_) => "ServerCreationError",
+    _ => "other error",
}

By @SimonSapin in #1614

Some error enums or variants were removed (Issue #81)

They were not used anymore in the public API (or at all).

By @SimonSapin in #1621

🚀 Features

Instrument the rhai plugin with a tracing span (PR #1598)

If you have an active rhai script in your router, you will now see a "rhai plugin" span in tracing.

By @garypen in #1598

🐛 Fixes

Only send one report for a response with deferred responses (PR #1576)

The router was sending one report per response (even deferred ones), while Studio was expecting one report for the entire
response. The router now sends one report which is inclusive of the latency of the entire operation.

By @Geal in #1576

Include formatted query plan when exposing the query plan (#1557)

Move the location of the text field when exposing the query plan and fill it with a formatted query plan.

By @bnjjj in #1557

Change state machine log messages to trace (#1578)

We no longer show internal state machine log events at the info level since they are unnecessary during normal operation. They are instead emitted at the trace level and can be enabled selectively using the --log trace flag.

By @abernix in #1597

Formatting problem fix of scalar fields selected several times (PR #1583)

Fixed a bug where querying scalar fields several times would put nulls instead of expected values.

By @eole1712 in #1585

Fix typo on HTTP errors from subgraph (#1593)

Remove the closed parenthesis at the end of error messages resulting from HTTP errors from subgraphs.

By @nmoutschen in #1593

Only send one report for a response with deferred responses (PR #1596)

Deferred responses come as multipart/mixed elements and are sent as individual HTTP response chunks. When a client receives one chunk,
that chunk should contain the next delimiter. This gives the client the ability to start processing the response instead of waiting for the
next chunk just for the delimiter.

By @Geal in #1596

Patch async-compression to compress responses in streaming (PR #1604)

The async-compression crate is a dependency used for HTTP response compression. Its implementation accumulates the entire compressed response in memory before sending it. However, this created problems for @defer responses since we want those responses to come as soon as
possible, rather than waiting until the entire total response has been received and compressed.

By @Geal in #1604

Queries with @defer must have the accept: multipart/mixed header (PR #1610)

Since deferred responses can come back as multipart responses, we must check that the client supports that content-type.
This will allow older clients to show a meaningful error message instead of a parsing error if the @defer directive is
used but they don't support it.

By @Geal in #1610

🛠 Maintenance

Depend on published router-bridge (PR #1613)

The router-bridge package is now published which means the router repository no longer depends on having Node.js installed to build.

By @o0Ignition0o in #1613

Re-organize our release steps check...

Read more

v0.16.0

22 Aug 14:54
2badb71
Compare
Choose a tag to compare

We're getting closer and closer to our 1.0 release and with that we have a lot of polish that we're applying to our API to get it ready for it to be a durable surface area for our consumers to depend on. Due to various learnings we've had during the pre-1.0 phases of the Router, we are evolving our API to match what we now know.

We do not intend on doing this much moving around of things again soon, but anyone who has been following the repository the last couple weeks knows there has been a lot of activity and discussion about where things should live. This means that this release has an abnormally high number of breaking changes, though we believe you'll find most of them to be relatively straightforward to pivot away from.

Please review the full change log to get all the details, but for the most part the changes in this release consist of:

  • a lot of renames of existing symbols
  • the re-location of exported symbols to more appropriate modules
  • the privatization of functions which we don't believe users needed directly (see below if any of these turn out to be a problem).

During each step of the migration, we recommend searching this changelog for a symbol to find advice on how to migrate it. We've tried to make the instructions and path forward as clear as possible.

  • If you find yourself needing help migrating to the new patterns, please first take a close look at the examples provided in this change log and if you still need help, please open a discussion.
  • If you find yourself unable to do something you had previously been able to do, please open an issue. Please make sure you include your use-case so we can understand better and document it for posterity!

We appreciate your patience working through these and we're excited for the steps ahead!

❗ BREAKING ❗

Remove QueryPlannerService (PR #1552)

This service was redundant, since anything done as part of the QueryPlannerService could be done either at the SupergraphService or at the ExecutionService level.

By @o0Ignition0o in #1552

Rename map_future_with_context to map_future_with_request_data (PR #1547)

The function is not very well named since it's in fact used to extract any data from a request for use in a future. This rename makes it clear.

By @garypen in #1547

Rename traffic shaping deduplication options (PR #1540)

In the traffic shaping module:

  • variables_deduplication configuration option is renamed to deduplicate_variables.
  • query_deduplication configuration option is renamed to deduplicate_query.
- traffic_shaping:
-   variables_deduplication: true # Enable the variables deduplication optimization
-   all:
-     query_deduplication: true # Enable query deduplication for all subgraphs.
-   subgraphs:
-     products:
-       query_deduplication: false # Disable query deduplication for products.
+ traffic_shaping:
+   deduplicate_variables: true # Enable the variables deduplication optimization
+   all:
+     deduplicate_query: true # Enable query deduplication for all subgraphs.
+   subgraphs:
+     products:
+       deduplicate_query: false # Disable query deduplication for products.

By @garypen in #1540

Make query_plan_options private and wrap QueryPlanContent in an opaque type (PR #1486)

QueryPlanOptions::query_plan_options is no longer public. If you still necessitate usage of this, please open an issue with your use case.

By @bnjjj in #1486

Removed delay_interval in telemetry configuration. (PR #1498)

It was doing nothing.

telemetry:
  metrics:
    common:
      # Removed, will now cause an error on Router startup:
      delay_interval:
        secs: 9
        nanos: 500000000

By @SimonSapin in #1498

Remove telemetry configuration hot reloading (PR #1463)

Configuration hot reloading is not very useful for telemetry, and is the
source of regular bugs that are hard to fix.

This removes the support for configuration reloading entirely. Now, the
router will reject a configuration reload with an error log if the
telemetry configuration changed.

It is now possible to create a subscriber and pass it explicitely to the telemetry plugin
when creating it. It will then be modified to integrate the telemetry plugin's layer.

By @geal in #1463

Reorder query planner execution (PR #1484)

Query planning is deterministic and only depends on the query, operation name and query planning
options. As such, we can cache the result of the entire process.

This changes the pipeline to apply query planner plugins between the cache and the bridge planner,
so those plugins will only be called once on the same query. If changes must be done per query,
they should happen in a supergraph service.

By @Geal in #1464

Remove Buffer from Mock*Service (PR #1440

This removes the usage of tower_test::mock::Mock in mocked services because it isolated the service in a task
so panics triggered by mockall were not transmitted up to the unit test that should catch it.
This rewrites the mocked services API to remove the build() method, and make them clonable if needed,
using an expect_clone call with mockall.

By @Geal in #1440

Some items were renamed or moved (PR #1487 PR #1534 PR #1555 PR #1563)

At the crate root:

  • SchemaKindSchemaSource
  • SchemaKind::String(String)SchemaSource::Static { schema_sdl: String }
  • ConfigurationKindConfigurationSource
  • ConfigurationKind::InstanceConfigurationSource::Static
  • ShutdownKindShutdownSource
  • ApolloRouterRouterHttpServer

In the apollo_router::plugin::Plugin trait:

  • router_servicesupergraph_service

In the apollo_router::services module, to new public sub-modules:

  • SupergraphRequestsupergraph::Request
  • SupergraphResponsesupergraph::Response
  • ExecutionRequestexecution::Request
  • ExecutionResponseexecution::Response
  • SubgraphRequestsubgraph::Request
  • SubgraphResponsesubgraph::Response

For convenience, these new sub-modules each contain type aliases
base on their respective Request and Response types.

pub type BoxService = tower::util::BoxService<Request, Response, tower::BoxError>;
pub type BoxCloneService = tower::util::BoxCloneService<Request, Response, tower::BoxError>;
pub type ServiceResult = Result<Response, tower::BoxError>;

Migration example:

-use tower::util::BoxService;
-use tower::BoxError;
-use apollo_router::services::{RouterRequest, RouterResponse};
+use apollo_router::services::router;
 
-async fn example(service: BoxService<RouterRequest, RouterResponse, BoxError>) -> RouterResponse {
+async fn example(service: router::BoxService) -> router::Response {
-    let request = RouterRequest::builder()/*…*/.build();
+    let request = router::Request::builder()/*…*/.build();
     service.oneshot(request).await
 }

By @SimonSapin in #1487, #1534, #1555, #1563

Some items were removed from the public API (PR #1487 PR #1535)

If you used some of them and don’t find a replacement,
please file an issue
with details about the use case.

apollo_router::Configuration::boxed
apollo_router::Configuration::is_compatible
apollo_router::errors::CacheResolverError
apollo_router::errors::JsonExtError
apollo_router::errors::ParsesError::print
apollo_router::errors::PlanError
apollo_router::errors::PlannerError
apollo_router::errors::PlannerErrors
apollo_router::errors::QueryPlannerError
apollo_router::errors::ServiceBuildError
apollo_router::json_ext
apollo_router::layers::ServiceBuilderExt::cache
apollo_router::mock_service!
apollo_router::plugins
apollo_router::plugin::plugins
apollo_router::plugin::PluginFactory
apollo_router::plugin::DynPlugin
apollo_router::plugin::Handler
apollo_router::plugin::test::IntoSchema
apollo_router::plugin::test::MockSubgraphFactory
apollo_router::plugin::test::PluginTestHarness
apollo_router::query_planner::QueryPlan::execute
apollo_router::services
apollo_router::Schema

By @SimonSapin...

Read more

v0.15.1

10 Aug 17:21
ac7607b
Compare
Choose a tag to compare

⚠️ SECURITY ⚠️

Landing page: Remove unsanitized example input

The default landing page contained HTML to display a sample curl command which is made visible if the full landing page bundle could not be fetched from Apollo's CDN. The server's URL is directly interpolated into this command inside the browser from window.location.href. On some older browsers such as IE11, this value is not URI-encoded. On such browsers, opening a malicious URL pointing at an Apollo Router could cause execution of attacker-controlled JavaScript. In this release, the fallback page does not display a curl command.

More details are available at the security advisory.

By @o0Ignition0o

Full Changelog: v0.15.0...v0.15.1