github apollographql/router v0.9.4

latest releases: v1.46.0, v1.46.0-rc.3, v1.46.0-rc.2...
23 months ago

❗ BREAKING ❗

Groundwork for @defer support (PR #1175, PR #1206)

To prepare for the implementation of the @defer directive, the ExecutionResponse and RouterResponse types now carry a stream of responses instead of a unique response. For now that stream contains only one item, so there is no change in behaviour. However, the Plugin trait changed to accomodate this, so a couple of steps are required to migrate your plugin so it is compatible with router v0.9.4:

  • Add a dependency to futures in your Cargo.toml:
+futures = "0.3.21"
  • Import BoxStream, and if your Plugin defines a router_service behavior, import ResponseBody:
+ use futures::stream::BoxStream;
+ use apollo_router::ResponseBody;
  • Update the router_service and the execution_service sections of your Plugin (if applicable):
      fn router_service(
         &mut self,
-        service: BoxService<RouterRequest, RouterResponse, BoxError>,
-    ) -> BoxService<RouterRequest, RouterResponse, BoxError> {
+        service: BoxService<RouterRequest, RouterResponse<BoxStream<'static, ResponseBody>>, BoxError>,
+    ) -> BoxService<RouterRequest, RouterResponse<BoxStream<'static, ResponseBody>>, BoxError> {

[...]

     fn execution_service(
         &mut self,
-        service: BoxService<ExecutionRequest, ExecutionResponse, BoxError>,
-    ) -> BoxService<ExecutionRequest, ExecutionResponse, BoxError> {
+        service: BoxService<ExecutionRequest, ExecutionResponse<BoxStream<'static, Response>>, BoxError>,
+    ) -> BoxService<ExecutionRequest, ExecutionResponse<BoxStream<'static, Response>>, BoxError> {

We can now update our unit tests so they work on a stream of responses instead of a single one:

         // Send a request
-        let result = test_harness.call_canned().await?;
-        if let ResponseBody::GraphQL(graphql) = result.response.body() {
+        let mut result = test_harness.call_canned().await?;
+
+        let first_response = result
+            .next_response()
+            .await
+            .expect("couldn't get primary response");
+
+        if let ResponseBody::GraphQL(graphql) = first_response {
             assert!(graphql.data.is_some());
         } else {
             panic!("expected graphql response")
         }

+        // You could keep calling result.next_response() until it yields None if you are expexting more parts.
+        assert!(result.next_response().await.is_none());
         Ok(())
     }

The apollo-router-core crate has been merged into apollo-router (PR #1189)

To upgrade, remove any dependency on the apollo-router-core crate from your Cargo.toml files and change imports like so:

- use apollo_router_core::prelude::*;
+ use apollo_router::prelude::*;

By @SimonSapin in #1189

Fix input validation rules (PR #1211)

The GraphQL specification provides two sets of coercion / validation rules, depending on whether we're dealing with inputs or outputs.
We have added validation rules for specified input validations which were not previously implemented.
This is a breaking change since slightly invalid input may have validated before but will now be guarded by newly-introduced validation rules.

By @o0Ignition0o in #1211

🚀 Features

Add trace logs for parsing recursion consumption (PR #1222)

The apollo-parser package now implements recursion limits which can be examined after the parsing phase. The router logs these
out at trace level. You can see them in your logs by searching for "recursion_limit". For example, when using JSON logging
and using jq to filter the output:

router -s ../graphql/supergraph.graphql -c ./router.yaml --log trace | jq -c '. | select(.fields.message == "recursion limit data")'
{"timestamp":"2022-06-10T15:01:02.213447Z","level":"TRACE","fields":{"message":"recursion limit data","recursion_limit":"recursion limit: 4096, high: 0"},"target":"apollo_router::spec::schema"}
{"timestamp":"2022-06-10T15:01:02.261092Z","level":"TRACE","fields":{"message":"recursion limit data","recursion_limit":"recursion limit: 4096, high: 0"},"target":"apollo_router::spec::schema"}
{"timestamp":"2022-06-10T15:01:07.642977Z","level":"TRACE","fields":{"message":"recursion limit data","recursion_limit":"recursion limit: 4096, high: 4"},"target":"apollo_router::spec::query"}

This example output shows that the maximum recursion limit is 4096 and that the query we processed caused us to recurse 4 times.

By @garypen in #1222

Helm chart now has the option to use an existing secrets for API key (PR #1196)

This change allows the use of an already existing secret for the graph API key.

To use existing secrets, update your own values.yaml file or specify the value on your helm install command line. For example:

helm install --set router.managedFederation.existingSecret="my-secret-name" <etc...>`

By @pellizzetti in #1196

Add iterators to Context (PR #1202)

Context can now be iterated over, with two new methods:

  • iter()
  • iter_mut()

These implementations lean heavily on an underlying DashMap implemetation, so refer to its documentation for more usage details.

By @garypen in #1202

Add an experimental optimization to deduplicate variables in query planner (PR #872)

Get rid of duplicated variables in requests and responses of the query planner. This optimization is disabled by default, if you want to enable it you just need override your configuration:

plugins:
  experimental.traffic_shaping:
    variables_deduplication: true # Enable the variables deduplication optimization

By @bnjjj in #872

Add more customizable metrics (PR #1159)

Added the ability to apply custom attributes/labels to metrics which are derived from header values using the Router's configuration file. For example:

telemetry:
  metrics:
    common:
      attributes:
        static:
          - name: "version"
            value: "v1.0.0"
        from_headers:
          - named: "content-type"
            rename: "payload_type"
            default: "application/json"
          - named: "x-custom-header-to-add"

By @bnjjj in #1159

Allow to set a custom health check path (PR #1164)

Added the possibility to set a custom health check path

server:
  # Default is /.well-known/apollo/server-health
  health_check_path: /health

By @jcaromiq in #1164

🐛 Fixes

Pin clap dependency in Cargo.toml (PR #1232)

A minor release of Clap occured yesterday which introduced a breaking change. This change might lead cargo scaffold users to hit a panic a runtime when the router tries to parse environment variables and arguments.

This patch pins the clap dependency to the version that was available before the release, until the root cause is found and fixed upstream.

By @o0Ignition0o in #1232

Display better error message when on subgraph fetch errors (PR #1201)

Show a helpful error message when a subgraph does not return JSON or a bad status code

By @bnjjj in #1201

Fix CORS configuration to eliminate runtime panic on misconfiguration (PR #1197)

Previously, it was possible to specify a CORS configuration which was syntactically valid, but which could not be enforced at runtime. For example, consider the following invalid configuration where the allow_any_origin and allow_credentials parameters are inherantly incompatible with each other (per the CORS specification):

server:
  cors:
    allow_any_origin: true
    allow_credentials: true

Previously, this would result in a runtime panic. The router will now detect this kind of misconfiguration and report the error without panicking.

By @garypen in #1197

🛠 Maintenance

Groundwork for @defer support (PR #1175PR #1206)

To prepare for the implementation of the @defer directive, the ExecutionResponse and RouterResponse types now carry a stream of responses instead of a unique response. For now that stream contains only one item, so there is no change in behaviour.

By @Geal in #1206

Fix a flappy test to test custom health check path (PR #1176)

Force the creation of SocketAddr to use a new unused port to avoid port collisions during testing.

By @bnjjj in #1176

Add static @skip/@include directive support (PR #1185)

  • Rewrite the InlineFragment implementation
  • Add support of static check for @include and @skip directives

By @bnjjj in #1185

Update buildstructor to 0.3 (PR #1207)

Update buildstructor to v0.3.

By @BrynCooke in #1207

Don't miss a new router release

NewReleases is sending notifications on new releases.