🚀 Features
Rhai Support at the router_service
(Issue #2278)
It is now possible to interact with some aspects of requests and responses at the router_service
level using Rhai-based customizations. The functionality is very similar to that provided for interacting with existing services, for example supergraph_service
. For instance, you may "map" requests and responses as follows:
fn router_service(service) {
const request_callback = Fn("process_request");
service.map_request(request_callback);
const response_callback = Fn("process_response");
service.map_response(response_callback);
}
The main difference from existing services is that the router_service
allows operating at an HTTP transport layer rather than the more structured GraphQL representations available at later service layers, like the supergraph service.
Initially, we are not allowing access to the body
property itself. This issue tracks changing that in the future. For now, it is possible to access the context
and headers
.
🐛 Fixes
Small performance improvements to telemetry (PR #3656)
We applied some small performance improvements to the SpanMetricsExporter
(which is used to report span timings), some of which apply in cases where telemetry is disabled and could be apparent to most users.
Handle interfaces in fragment spreads when __typename
is omitted (Issue #2587)
We now check the parent type when using an inline-fragment, rather than relying on the expectation that __typename
will be present. For cases where __typename
was being omitted, this fixes responses where a portion of the selection set was silently dropped and not returned.
By @o0Ignition0o and @Geal in #3718
Deduplication is, again, enabled by default as documented (PR #3773)
Subscription deduplication is again enabled by default as it was intended to be. This important performance feature for subscriptions at scale was inadvertently disabled in v1.25.0 due to a bug.
To explicitly disable deduplication, set enable_deduplication
to false
in your configuration.
Metrics are no longer coerced incorrectly (Issue #3687)
Metric attributes are no longer incorrectly coerced to strings. In addition, the logic around types which are accepted as metrics attributes has been simplified to avoid this in the future. Going forward, if the wrong type is specified, values will be ignored and a log message (at debug level) will be emitted.
By @BrynCooke in #3724
Optimizations applied to header-handling operations (Issue #3068)
Latency and overhead of passing headers to subgraph queries has been reduced.
Avoid request overhead when telemetry is not enabled
The overhead of OpenTelemetry has been removed when no tracing exporters are configured.
This also improves performance when sampling criteria has not been met by preventing unsampled sampled trace events from propagating to the rest of the OpenTelemetry stack.
Subgraph authentication: Apply signature after compression and APQ (Issue #3608)
The router will now sign subgraph requests just before they are sent to the subgraph (i.e., a bit later than previously), following up on the functionality of subgraph authentication which was first introduced in v1.27.0.
This fixes interactions with:
- Subgraph Automatic Persisted Queries (APQ)
- Subgraph HTTP compression
- Custom plugins that operate on the subgraph service (whether via Co-Processors, Rhai or a compiled Rust plugin)
In most cases, the interactions between these features and the subgraph authentication feature were problematic and required disabling one or the other in order to generate a request that was correctly signed by the signature algorithm. This should all be resolved.
By @o0Ignition0o in #3735
Handle multipart stream if the original stream was empty (Issue #3293)
Multi-part response streams (which are used for subscriptions and operations which include @defer
directive) are now terminated correctly when the response stream is empty.
Subscriptions: Include x-accel-buffering
header on multipart responses (Issue #3683)
Setting the x-accel-buffering
header to no
for multipart responses allows certain proxies to configure themselves in a mode that is compatible with the buffering used by subscriptions. This improves Subscriptions' compatibility with existing infrastructure.
🛠 Maintenance
Our Rust Toolchain has been updated to v1.72.0 (PR #3707)
Our Rust Toolchain has been updated to v1.72.0. For the majority of our users (those who do not compile their own Router from source), this change will not have any impact. Otherwise, Rust 1.72.0 can now be used.
By @o0Ignition0o in #3707
Replace atty
crate with std
(PR #3729)
To resolve a security advisory (for which our usage was not affected), we've replaced atty
with std
. Instead, we now use equivalent functionality available in the Rust standard library, available since Rust v1.70.0.
- https://github.com/apollographql/router/security/dependabot/68
- https://doc.rust-lang.org/stable/std/io/trait.IsTerminal.html
By @SimonSapin in #3729
Upgrade webpki
and rustls-webpki
(PR #3728)
These two dependency updates brings fixes for two separate security advisories:
Since Apollo Router does not accept client certificates, it could only have been affected if a subgraph had provided a pathological TLS server certificate.
By @SimonSapin in #3728
📚 Documentation
GraphOS authorization: Exemplify scope manipulation with Rhai at the router service level (PR #3719)
New Authorization documentation shows the how to use Rhai script to extract scopes and prepare them in the correct way, for use with @requiresScope
. This becomes relevant since @requiresScopes
expects scopes to come from the scope
claim in the OAuth2 access token format while tokens may have scopes stored differently, e.g., as an array of strings, or even as different claims. If you have further questions on the right choice for you, please open a GitHub Discussion that provides an example of what you need to achieve.