🚀 Features
TLS client authentication for subgraph requests (Issue #3414)
The router now supports TLS client authentication when connecting to subgraphs. It can be configured as follows:
tls:
subgraph:
all:
client_authentication:
certificate_chain:
key:
# if configuring for a specific subgraph:
subgraphs:
# subgraph name
products:
client_authentication:
certificate_chain:
key:
Details on TLS client authentication can be found in the documentation
Added configuration to set redis request timeout (Issue #3621)
We added configuration to override default timeout for Redis requests. Default timeout was also changed from 1ms to 2ms.
Here is an example to change the timeout for Distributed APQ (an Enterprise Feature):
apq:
router:
cache:
redis:
urls: ["redis://..."]
timeout: 5ms
JSON encoding and decoding in Rhai (PR #3785)
It is now possible to encode or decode JSON from Rhai scripts using json::encode
and json::decode
.
Supergraph coprocessor implementation (PR #3647)
Coprocessors now support supergraph service interception.
On the request side, the coprocessor payload can contain:
- method
- headers
- body
- context
- sdl
On the response side, the payload can contain:
- status_code
- headers
- body
- context
- sdl
The supergraph request body contains:
- query
- operation name
- variables
- extensions
The supergraph response body contains:
- label
- data
- errors
- extensions
When using @defer
or subscriptions a supergraph response may contain multiple GraphQL responses. The coprocessor will be called for each response. Please refer to our coprocessor documentation for more information.
Adds support for the OpenTelemetry AWS X-Ray tracing propagator (PR #3580)
This propagator helps propagate tracing information from upstream services (such as AWS load balancers) to downstream services. It also handles conversion between the X-Ray trace id format and OpenTelemetry span contexts.
By @scottmace in #3580
HTTP/2 Cleartext protocol (H2C) support for subgraph connections (Issue #3535)
The router can now connect to subgraphs over HTTP/2 Cleartext (H2C), which uses the HTTP/2 binary protocol directly over TCP without TLS, which is a mode of operation desired with some service mesh configurations (e.g., Istio, Envoy) where the value of added encryption is unnecessary. To activate it, set the experimental_http2
option to http2_only
.
Query plan cache warm-up improvements (Issue #3704, Issue #3767)
The warm_up_queries
option enables quicker schema updates by precomputing query plans for your most used cached queries and your persisted queries. When a new schema is loaded, a precomputed query plan for it may already be in the in-memory cache.
We made a series of improvements to this feature to make it easier to use:
- It is now active by default.
- It warms up the cache with the 30% most used queries from previous cache.
- The query cache percentage continues to be configurable, and it can be deactivated by setting it to 0.
- The warm-up will now plan queries in random order to make sure that the work can be shared by multiple router instances using distributed caching.
- Persisted queries are part of the warmed up queries.
We also added histogram metrics for apollo_router_query_planning_warmup_duration
and apollo_router_schema_load_duration
. These metrics make it easier to track the time spent loading a new schema and planning queries in the warm-up phase. You can measure the query plan cache usage for both the in-memory-cache and distributed cache. This makes it easier to know how many entries are used as well as the cache hit rate.
Here is what these metrics would look like in Prometheus:
# HELP apollo_router_query_planning_warmup_duration apollo_router_query_planning_warmup_duration
# TYPE apollo_router_query_planning_warmup_duration histogram
apollo_router_query_planning_warmup_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.05"} 1
apollo_router_query_planning_warmup_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.1"} 1
apollo_router_query_planning_warmup_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.25"} 1
apollo_router_query_planning_warmup_duration_sum{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version=""} 0.022390619
apollo_router_query_planning_warmup_duration_count{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version=""} 1
# HELP apollo_router_schema_load_duration apollo_router_schema_load_duration
# TYPE apollo_router_schema_load_duration histogram
apollo_router_schema_load_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.05"} 8
apollo_router_schema_load_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.1"} 8
apollo_router_schema_load_duration_bucket{service_name="apollo-router",otel_scope_name="apollo/router",otel_scope_version="",le="0.25"} 8
You can get more information about operating the query plan cache and its warm-up phase in the documentation
By @Geal in #3815 #3801 #3767 #3769 #3770
🐛 Fixes
Fix error response on large number types in query transformations (PR #3820)
This bug caused the router to reject operations where a large hardcoded integer was used as input for a Float field:
# Schema
type Query {
field(argument: Float): Int!
}
# Operation
{
field(argument: 123456789123)
}
This number is now correctly interpreted as a Float
. This bug only affected hardcoded numbers, not numbers provided through variables.
By @goto-bus-stop in #3820
Fix validation error with ID
variable values overflowing 32-bit integers (Issue #3873)
Input values for variables of type ID
were previously validated as "either like a GraphQL Int
or like a GraphQL String
". GraphQL Int
is specified as a signed 32-bit integer, such that values that overflow fail validation. Applying this range restriction to ID
values was incorrect. Instead, validation for ID
now accepts any JSON integer or JSON string value, so that IDs larger than 32 bits can be used.
By @SimonSapin in #3896
Improve multi-cloud failover and error handling for Persisted Queries (PR #3863)
Improves the resilience of the Persisted Queries feature to Uplink outages. This makes errors while fetching persisted query manifests from Uplink more visible.
Coprocessors: Discard content-length sent by coprocessors (PR #3802)
The content-length
of an HTTP response can only be computed when a router response is being sent.
We now discard coprocessors content-length
header to make sure the value is computed correctly.
By @o0Ignition0o in #3802
Helm: If there are extraLabels
add them to all resources (PR #3622)
This extends the functionality of extraLabels
so that, if they are defined, they will be templated for all resources created by the chart.
Previously, they were only templated onto the Deployment
resource.
By @garypen and @bjoernw in #3622
📚 Documentation
Rhai documentation: remove incorrect statement about request.subgraph fields (PR #3808)
It is possible to modify request.subgraph
fields from a Rhai script, which is now correctly reflected in Rhai documentation.