Skip to content

Releases: apollographql/router

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

v0.15.0

09 Aug 16:29
1764cd6
Compare
Choose a tag to compare

❗ BREAKING ❗

CORS: Deprecate newly-added allow_any_header option and return to previous behavior (PR https://github.com/apollographql/router/pull/1480)

We've re-considered and reverted changes we shipped in the last release with regards to how we handle the Access-Control-Request-Headers request header and its corresponding Access-Control-Allow-Headers response header. We've reverted to the previous releases' behavior, including the removal of the recently-added allow_any_header option.

The previous default behavior was to reflect the client's Access-Control-Request-Headers request header values back in the Access-Control-Allow-Headers response header. This previous behavior is in fact a common default behavior in other CORS libraries as well, including the cors Node.js package and we think it's worth keeping as it was previously, rather than requiring users to specify allow_any_header for the majority of use cases. We believe this to be a safe and secure default that is also more user-friendly.

It is not typically necessary to change this default behavior, but if you wish to allow a more specific set of headers, you can disable the default header reflection and specify a list of headers using the allow_headers option, which will allow only those headers in negotiating a response:

server:
  cors:
    allow_any_origin: true
    # Including this `allow_headers` isn't typically necessary (can be removed) but
    # will *restrict* the permitted Access-Control-Allow-Headers response values.
    allow_headers:
      - Content-Type
      - Authorization
      - x-my-custom-header

By @o0Ignition0o in #1480

Reference-counting for the schema string given to plugins (PR https://github.com/apollographql/router/pull/1462)

The type of the supergraph_sdl field of the apollo_router::plugin::PluginInit struct
was changed from String to Arc<String>.
This reduces the number of copies of this string we keep in memory, as schemas can get large.

By @SimonSapin in #1462

🐛 Fixes

Update span attributes to be compliant with the opentelemetry for GraphQL specs (PR https://github.com/apollographql/router/pull/1449)

Change attribute name query to graphql.document and operation_name to graphql.operation.name in spans.

By @bnjjj in #1449

Configuration handling enhancements (PR https://github.com/apollographql/router/pull/1454)

Router config handling now:

  • Allows completely empty configuration without error.
  • Prevents unknown tags at the root of the configuration from being silently ignored.

By @BrynCooke in #1454

📚 Documentation

CORS: Fix trailing slashes, and display defaults (PR https://github.com/apollographql/router/pull/1471)

The CORS documentation now displays a valid origins configuration (without trailing slash!), and the full configuration section displays its default settings.

By @o0Ignition0o in #1471

Add helm OCI example (PR https://github.com/apollographql/router/pull/1457)

Update existing filesystem based example to illustrate how to do the same thing using our OCI stored helm chart.

By @garypen in #1457

v0.14.0

02 Aug 15:10
9c0864c
Compare
Choose a tag to compare

❗ BREAKING ❗

Regex allow_any_origin behavior changed (PR #1444)

Setting allow_any_origin to true in the router configuration would previously automatically mirror the requested headers.
If you relied on this behavior, you now also need to set allow_any_header to true, as explained in the CORS documentation.

server:
  cors:
    allow_any_origin: true
    allow_any_header: true # mirror client's headers

The default CORS headers configuration of the router allows content-type, apollographql-client-version and apollographql-client-name.

By @o0Ignition0o in #1444

Modify the plugin new method to pass an initialisation structure (PR #1446)

This change alters the new method for plugins to pass a PluginInit struct.

We are making this change so that we can pass more information during plugin startup. The first change is that in addition to passing
the plugin configuration, we are now also passing the router supergraph sdl (Schema Definition Language) as a string.

There is a new example (supergraph_sdl) which illustrates how to use this new capability.

By @garypen in #1446

Remove the generic stream type from RouterResponse and ExecutionResponse (PR #1420)

This generic type complicates the API with limited benefit because we use BoxStream everywhere in plugins:

  • RouterResponse<BoxStream<'static, Response>> -> RouterResponse
  • ExecutionResponse<BoxStream<'static, Response>> -> ExecutionResponse

By @Geal in #1420

Remove the HTTP request from QueryPlannerRequest (PR #1439)

The content of QueryPlannerRequest is used as argument to the query planner and as a cache key,
so it should not change depending on the variables or HTTP headers.

By @Geal in #1439

Change PluggableRouterServiceBuilder methods (PR #1437)

with_naive_introspection and with_defer_support where two parameter-less methods
of this builder that enabled boolean configuration flags.
They have been removed and replaced by with_configuration
which takes Arc<apollo_router::Configuration>.
A Configuration value can be created from various formats by deserializing with serde.
The removed methods correspond to server.introspection and server.experimental_defer_support
configuration keys respectively.

By @SimonSapin in #1437

Changes to the SchemaKind enum (PR #1437)

The Instance variant is replaced with a variant named String that contains…
a String instead of Box<apollo_router::Schema>,
so you no longer need to parse the schema before giving it to the router.
Similarly, the Stream variant now contains a stream of Strings
instead of a stream of already-parsed Schemas.

By @SimonSapin in #1437

Schema no longer implements FromStr (PR #1437)

This means that str.parse::<apollo_router::Schema>() is no longer available.
If you still need a parsed Schema (see above),
use apollo_router::Schema(str, &configuration) instead.
To use the default apollo_router::Configuration
you can call apollo_router::Schema(str, &Default::default()).

By @SimonSapin in #1437

🚀 Features

Publish helm chart to OCI registry (PR #1447)

When we make a release, publish our helm chart to the same OCI registry that we use for our docker images.

For more information about using OCI registries with helm, see the helm documentation.

By @garypen in #1447

Configure Regex based CORS rules (PR #1444)

The router now supports regex based CORS rules, as explained in the docs
It also supports the allow_any_header setting that will mirror client's requested headers.

server:
  cors:
    match_origins:
      - "https://([a-z0-9]+[.])*api[.]example[.]com" # any host that uses https and ends with .api.example.com
    allow_any_header: true # mirror client's headers

The default CORS headers configuration of the router allows content-type, apollographql-client-version and apollographql-client-name.

By @o0Ignition0o in #1444

Add support of error section in telemetry to add custom attributes (PR #1443)

The telemetry is now able to hook at the error stage if router or a subgraph is returning an error. Here is an example of configuration:

telemetry:
  metrics:
    prometheus:
      enabled: true
    common:
      attributes:
        subgraph:
          all:
            errors: # Only works if it's a valid GraphQL error
              include_messages: true # Will include the error message in a message attribute
              extensions: # Include extension data
                - name: subgraph_error_extended_type # Name of the attribute
                  path: .type # JSON query path to fetch data from extensions

By @bnjjj in #1443

Experimental support for the @defer directive (PR #1182)

The router can now understand the @defer directive, used to tag parts of a query so the response is split into
multiple parts that are sent one by one.

⚠️ this is still experimental and not fit for production use yet

To activate it, add this option to the configuration file:

server:
  experimental_defer_support: true

By @Geal in #1182

Rewrite the caching API (PR #1281)

This introduces a new asynchronous caching API that opens the way to multi level caching (in memory and
database). The API revolves around an Entry structure that allows query deduplication and lets the
client decide how to generate the value to cache, instead of a complicated delegate system inside the
cache.

By @Geal in #1281

🐛 Fixes

Update serialization format for telemetry.tracing.otlp.grpc.metadata (PR #1391)

The metadata format now uses IndexMap<String, Vec<String>>.

By @me-diru in #1391

Update the scaffold template so it targets router v0.14.0 (PR #1431)

The cargo scaffold template will target the latest version of the router.

By @o0Ignition0o in #1248

Selection merging on non-object field aliases (PR #1406)

Fixed a bug where merging aliased fields would sometimes put nulls instead of expected values.

By @o0Ignition0o in #1432

A Rhai error instead of a Rust panic ([PR #1414 https://github.com//pull/1414))

In Rhai plugins, accessors that mutate the originating request are not available when in the subgraph phase. Previously, trying to mutate anyway would cause a Rust panic. This has been changed to a Rhai error instead.

By @SimonSapin in #1414

Optimizations (PR #1423)

  • Do not clone the client request during query plan execution
  • Do not clone the usage reporting
  • Avoid path allocations when iterating over JSON values

The benchmarks show that this change brings a 23% gain in requests per second compared to the main branch.

By @Geal in #1423

do not perform nested fetches if the parent one returned null (PR #1332

In a query of the form:

mutation {
	mutationA {
		mutationB
	}
}

If mutationA returned null, we should not execute mutationB.

By @Ty3uK in #1332

🛠 Maintenance

📚 Documentation

Updates wording and formatting of README.md

By @EverlastingBugstopper in #1445

What's Changed

Read more