v0.9.4
β 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 arouter_service
behavior, importResponseBody
:
+ use futures::stream::BoxStream;
+ use apollo_router::ResponseBody;
- Update the
router_service
and theexecution_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.
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.
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
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"
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
π 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
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.
π 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.
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.
Add static @skip
/@include
directive support (PR #1185)
- Rewrite the
InlineFragment
implementation - Add support of static check for
@include
and@skip
directives
Update buildstructor
to 0.3 (PR #1207)
Update buildstructor
to v0.3.
By @BrynCooke in #1207