Releases: apollographql/router
v0.1.0-preview.1
🎉 The Apollo Router has graduated to its Preview phase! 🎉
❗ BREAKING ❗
-
Improvements to telemetry attribute YAML ergonomics (PR #729)
Trace config YAML ergonomics have been improved. To add additional attributes to your trace information, you can now use the following format:
trace_config: attributes: str: "a" int: 1 float: 1.0 bool: true str_arr: - "a" - "b" int_arr: - 1 - 2 float_arr: - 1.0 - 2.0 bool_arr: - true - false
🐛 Fixes
-
Log and error message formatting (PR #721)
Logs and error messages now begin with lower case and do not have trailing punctuation, per Rust conventions.
-
OTLP default service.name and service.namespace (PR #722)
While the Jaeger YAML configuration would default to
router
for theservice.name
and toapollo
for theservice.namespace
, it was not the case when using a configuration that utilized OTLP. This lead to anUNKNOWN_SERVICE
name span in zipkin traces, and difficult to find Jaeger traces.
v0.1.0-preview.0
🎉 The Apollo Router has graduated to its Preview phase! 🎉
For more information on what's expected at this stage, please see our release stages.
🐛 Fixes
-
Header propagation by
name
only fixed (PR #709)
Previouslyrename
anddefault
values were required (even though they were correctly not flagged as required in the json schema).
The following will now work:headers: all: - propagate: named: test
-
Fix OTLP hang on reload (PR #711)
Fixes hang when OTLP exporter is configured and configuration hot reloads.
v0.1.0-alpha.10
❗ BREAKING ❗
-
Header propagation
remove
'sname
is nownamed
(PR #674)This merely renames the
remove
options'name
setting to be insteadnamed
to be a bit more intuitively named and consistent with its partner configuration,propagate
.Previous configuration
# Remove a named header - remove: name: "Remove" # Was: "name"
New configuration
# Remove a named header - remove: named: "Remove" # Now: "named"
-
Command-line flag vs Environment variable precedence changed (PR #693)
For logging related verbosity overrides, the
RUST_LOG
environment variable no longer takes precedence over the command line argument. The full order of precedence is now command-line argument overrides environment variable overrides the default setting.
🚀 Features
-
Forbid mutations plugin (PR #641)
The forbid mutations plugin allows you to configure the router so that it disallows mutations. Assuming none of your
query
requests are mutating data or changing state (they shouldn't!) this plugin can be used to effectively make your graph read-only. This can come in handy when testing the router, for example, if you are mirroring/shadowing traffic when trying to validate a Gateway to Router migration! 😸 -
⚠️ Add experimental Rhai plugin (PR #484)Add an experimental core plugin to be able to extend Apollo Router functionality using Rhai script. This allows users to write their own
*_service
function similar to how as you would with a native Rust plugin but without needing to compile a custom router. Rhai scripts have access to the request context and headers directly and can make simple manipulations on them.See our Rhai script documentation for examples and details!
🐛 Fixes
-
Correctly set the URL path of the HTTP request in
RouterRequest
(Issue #699)Previously, we were not setting the right HTTP path on the
RouterRequest
so when writing a plugin withrouter_service
you always had an empty path/
onRouterRequest
.
📚 Documentation
-
We have incorporated a substantial amount of documentation (via many, many PRs!)
See our improved documentation on our website.
v0.1.0-alpha.9
❗ BREAKING ❗
-
Header propagation configuration changes (PR #599)
Header manipulation configuration is now a core-plugin and configured at the top-level of the Router's configuration file, rather than its previous location within service-level layers. Some keys have also been renamed. For example:
Previous configuration
subgraphs: products: layers: - headers_propagate: matching: regex: .*
New configuration
headers: subgraphs: products: - propagate: matching: ".*"
-
Move Apollo plugins to top-level configuration (PR #623)
Previously plugins were all under the
plugins:
section of the YAML config. However, these "core" plugins are now promoted to the top-level of the config. This reflects the fact that these plugins provide core functionality even though they are implemented as plugins under the hood and further reflects the fact that they receive special treatment in terms of initialization order (they are initialized first before members ofplugins
). -
Remove configurable layers (PR #603)
Having
plugins
andlayers
as configurable items in YAML was creating confusion as to when it was appropriate to use alayer
vs aplugin
. As the layer API is a subset of the plugin API,plugins
has been kept, however thelayer
option has been dropped. -
Plugin names have dropped the
com.apollographql
prefix (PR #602)Previously, core plugins were prefixed with
com.apollographql.
. This is no longer the case and, when coupled with the above moving of the core plugins to the top-level, the prefixing is no longer present. This means that, for example,com.apollographql.telemetry
would now be justtelemetry
. -
Use
ControlFlow
in checkpoints (PR #602)Both
checkpoint
andasync_checkpoint
nowuse std::ops::ControlFlow
instead of theStep
enum.ControlFlow
has two variants,Continue
andBreak
. -
The
reporting
configuration changes totelemetry
(PR #651)All configuration that was previously under the
reporting
header is now under atelemetry
key.
✨ Features
-
Header propagation now supports "all" subgraphs (PR #599)
It is now possible to configure header propagation rules for all subgraphs without needing to explicitly name each subgraph. You can accomplish this by using the
all
key, under the (now relocated; see above breaking changes)headers
section.headers: all: - propagate: matching: "aaa.*" - propagate: named: "bbb" default: "def" rename: "ccc" - insert: name: "ddd" value: "eee" - remove: matching: "fff.*" - remove: name: "ggg"
-
Update to latest query planner from Federation 2 (PR #653)
The Router now uses the
@apollo/query-planner@2.0.0-preview.5
query planner, bringing the most recent version of Federation 2.
🐛 Fixes
-
Content-Type
of HTTP responses is now set toapplication/json
(Issue #639)Previously, we were not setting a
content-type
on HTTP responses. While plugins can still set a differentcontent-type
if they'd like, we now ensure that acontent-type
ofapplication/json
is set when one was not already provided. -
GraphQL Enums in query parameters (Issue #612)
Enums in query parameters were handled correctly in the response formatting, but not in query validation. We now have a new test and a fix.
-
OTel trace propagation works again (PR #620)
When we re-worked our OTel implementation to be a plugin, the ability to trace across processes (into subgraphs) was lost. This fix restores this capability. We are working to improve our end-to-end testing of this to prevent further regressions.
-
Reporting plugin schema generation (PR #607)
Previously our
reporting
plugin configuration was not able to participate in JSON Schema generation. This is now broadly correct and makes writing a syntactically-correct schema much easier.To generate a schema, you can still run the same command as before:
router --schema > apollo_configuration_schema.json
Then, follow the instructions for associating it with your development environment.
-
Input object validation (PR #658)
Variable validation was incorrectly using output objects instead of input objects
v0.1.0-alpha.8
✨ Features
-
Request lifecycle checkpoints (PR #558 and PR #580)
Checkpoints in the request pipeline now allow plugin authors (which includes us!) to check conditions during a request's lifecycle and circumvent further execution if desired.
Using
Step
return types within the checkpoint it's possible to influence what happens (including changing things like the HTTP status code, etc.). A caching layer, for example, could returnStep::Return(response)
if a cache "hit" occurred andStep::Continue(request)
(to allow normal processing to continue) in the event of a cache "miss".These can be either synchronous or asynchronous. To see examples, see:
-
Contracts support (PR #573)
The Apollo Router now supports Apollo Studio Contracts!
-
Add OpenTracing support (PR #548)
OpenTracing support has been added into the reporting plugin. You're now able to have span propagation (via headers) via two common formats supported by the
opentracing
crate:zipkin_b3
andjaeger
.
🐛 Fixes
-
Configuration no longer requires
router_url
(PR #553)When using Managed Federation or directly providing a Supergraph file, it is no longer necessary to provide a
routing_url
value. Instead, the values provided by the Supergraph or Studio will be used and therouting_url
can be used only to override specific URLs for specific subgraphs. -
Fix plugin ordering (PR #559)
Plugins need to execute in sequence of declaration except for certain "core" plugins (e.g., reporting) which must execute early in the plugin sequence to make sure they are in place as soon as possible in the Router lifecycle. This change now ensures that the reporting plugin executes first and that all other plugins are executed in the order of declaration in configuration.
-
Propagate Router operation lifecycle errors (PR #537)
Our recent extension rework was missing a key part: Error propagation and handling! This change makes sure errors that occurred during query planning and query execution will be displayed as GraphQL errors instead of an empty payload.
v0.1.0-alpha.7
✨ Features
-
Apollo Studio Explorer landing page (PR #526)
We've replaced the redirect to Apollo Studio with a statically rendered landing page. This supersedes the previous redirect approach was merely introduced as a short-cut. The experience now duplicates the user-experience which exists in Apollo Gateway today.
It is also possible to save the redirect preference and make the behavior sticky for future visits. As a bonus, this also resolves the failure to preserve the correct HTTP scheme (e.g.,
https://
) in the event that the Apollo Router was operating behind a TLS-terminating proxy, since the redirect is now handled client-side.Overall, this should be a more durable and more transparent experience for the user.
-
Display Apollo Router version on startup (PR #543)
The Apollo Router displays its version on startup from now on, which will come in handy when debugging/observing how your application behaves.
🐛 Fixes
-
Passing a
--supergraph
file supersedes Managed Federation (PR #535)The
--supergraph
flag will no longer be silently ignored when the Supergraph is already being provided through Managed Federation (i.e., when theAPOLLO_KEY
andAPOLLO_GRAPH_REF
environment variables are set). This allows temporarily overriding the Supergraph schema that is fetched from Apollo Studio's Uplink endpoint, while still reporting metrics to Apollo Studio reporting ingress. -
Anonymous operation names are now empty in tracing (PR #525)
When GraphQL operation names are not necessary to execute an operation (i.e., when there is only a single operation in a GraphQL document) and the GraphQL operation is not named (i.e., it is anonymous), the
operation_name
attribute on the trace spans that are associated with the request will no longer contain a single hyphen character (-
) but will instead be an empty string. This matches the way that these operations are represented during the GraphQL operation's life-cycle as well. -
Resolved missing documentation in Apollo Explorer (PR #540)
We've resolved a scenario that prevented Apollo Explorer from displaying documentation by adding support for a new introspection query which also queries for deprecation (i.e.,
includeDeprecated
) oninput
arguments.
v0.1.0-alpha.6
✨ Features
-
Apollo Studio Managed Federation support (PR #498)
The Router can now automatically download and check for updates on its schema from Studio (via Uplink)'s free, Managed Federation service. This is configured in the same way as Apollo Gateway via the
APOLLO_KEY
andAPOLLO_GRAPH_REF
environment variables, in the same way as was true in Apollo Gateway (seen here). This will also enable operation usage reporting.Note: It is not yet possible to configure the Router with
APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT
. If you need this behavior, please open a feature request with your use case. -
Subgraph header configuration (PR #453)
The Router now supports passing both client-originated and router-originated headers to specific subgraphs using YAML configuration. Each subgraph which needs to receive headers can specify which headers (or header patterns) should be forwarded to which subgraph.
More information can be found in our documentation on subgraph header configuration.
At the moment, when using using YAML configuration alone, router-originated headers can only be static strings (e.g.,
sent-from-apollo-router: true
). If you have use cases for deriving headers in the router dynamically, please open or find a feature request issue on the repository which explains the use case. -
In-flight subgraph
query
de-duplication (PR #285)As a performance booster to both the Router and the subgraphs it communicates with, the Router will now de-duplicate multiple identical requests to subgraphs when there are multiple in-flight requests to the same subgraph with the same
query
(nevermutation
s), headers, and GraphQLvariables
. Instead, a single request will be made to the subgraph and the many client requests will be served via that single response.There may be a substantial drop in number of requests observed by subgraphs with this release.
-
Operations can now be made via
GET
requests (PR #429)The Router now supports
GET
requests forquery
operations. Previously, the Apollo Router only supported making requests viaPOST
requests. We've always intended on supportingGET
support, but needed some additional support in place to make sure we could prevent allowingmutation
s to happen overGET
requests. -
Automatic persisted queries (APQ) support (PR #433)
The Router now handles automatic persisted queries (APQ) by default, as was previously the case in Apollo Gateway. APQ support pairs really well with
GET
requests (which also landed in this release) since they allow read operations (e.g.,GET
requests) to be more easily cached by intermediary proxies and CDNs, which typically forbid cachingPOST
requests by specification (even if they often are just reads in GraphQL). Follow the link above to the documentation to test them out. -
New internal Tower architecture and preparation for extensibility (PR #319)
We've introduced new foundational primitives to the Router's request pipeline which facilitate the creation of composable onion layers. For now, this is largely leveraged through a series of internal refactors and we'll need to document and expand on more of the details that facilitate developers building their own custom extensions. To leverage existing art — and hopefully maximize compatibility and facilitate familiarity — we've leveraged the Tokio Tower
Service
pattern.This should facilitate a number of interesting extension opportunities and we're excited for what's in-store next. We intend on improving and iterating on the API's ergonomics for common Graph Router behaviors over time, and we'd encourage you to open issues on the repository with use-cases you might think need consideration.
-
Support for Jaeger HTTP collector in OpenTelemetry (PR #479)
It is now possible to configure Jaeger HTTP collector endpoints within the
opentelemetry
configuration. Previously, Router only supported the UDP method.The documentation has also been updated to demonstrate how this can be configured.
🐛 Fixes
-
Studio agent collector now binds to localhost PR #486
The Studio agent collector will bind to
127.0.0.1
. It can be configured to bind to0.0.0.0
if desired (e.g., if you're using the collector to collect centrally) by using thespaceport.listener
property in the documentation.
v0.1.0-alpha.5
✨ Features
-
Apollo Studio usage reporting agent and operation-level reporting (PR #309, PR #420)
While there are several levels of Apollo Studio integration, the initial phase of our Apollo Studio reporting focuses on operation-level reporting. This can be configured using the instructions in our documentation.
At a high-level, this will allow Apollo Studio to have visibility into some basic schema details, like graph ID and variant, and per-operation details, including:
- Overall operation latency
- The number of times the operation is executed
- Client awareness reporting, which leverages the
apollographql-client-*
headers to give visibility into which clients are making which operations.
This should enable several Apollo Studio features including the Clients and Checks pages as well as the Usage tab on the Operations page.
Note: As a current limitation, the Fields page will not have detailed field-based metrics and on the Operations page the Errors tab, the Traces tab and the Error Percentage graph will not receive data. We recommend configuring the Router's OpenTelemetry tracing with your APM provider and using distributed tracing to increase visibility into individual resolver performance.
Overall, this marks a notable but still incremental progress toward more of the Studio integrations which are laid out in #66.
-
Complete GraphQL validation (PR #471 via federation-rs#37)
We now apply all of the standard validations which are defined in the
graphql
(JavaScript) implementation's default set of "specified rules" during query planning.
🐛 Fixes
-
No more double
http://http://
in logs (PR #448)The server logs will no longer advertise the listening host and port with a doubled-up
http://
prefix. You can once again click happily into Studio Explorer! -
Improved handling of Federation 1 supergraphs (PR #446 via federation#1511)
Our partner team has improved the handling of Federation 1 supergraphs in the implementation of Federation 2 alpha (which the Router depends on and is meant to offer compatibility with Federation 1 in most cases). We've updated our query planner implementation to the version with the fixes.
This also was the first time that we've leveraged the new
federation-rs
repository to handle our bridge, bringing a huge developmental advantage to teams working across the various concerns! -
Resolved incorrect subgraph ordering during merge (PR #460)
A fix was applied to fix the behavior which was identified in Issue #451 which was caused by a misconfigured filter which was being applied to field paths.
v0.1.0-alpha.4
✨ Features
-
Unix socket support via #158
...and via upstream
tokios-rs/tokio#4385
The Router can now listen on Unix domain sockets (i.e., IPC) in addition to the existing IP-based (port) listening. This should bring further compatibility with upstream intermediaries who also allow support this form of communication!
(Thank you to @cecton, both for the PR that landed this feature but also for contributing the upstream PR to
tokio
.)
🐛 Fixes
-
Resolved hangs occurring on Router reload when
jaeger
was configured via #337Synchronous calls being made to
opentelemetry::global::set_tracer_provider
were causing the runtime to misbehave when the configuration (file) was adjusted (and thus, hot-reloaded) on account of the root context of that call being asynchronous.This change adjusts the call to be made from a new thread. Since this only affected potential runtime configuration changes (again, hot-reloads on a configuration change), the thread spawn is a reasonable solution.
💅 Improvements
Most of the improvements this time are internal to the code-base but that doesn't mean we shouldn't talk about them. A great developer experience matters both internally and externally! 😸
-
Store JSON strings in a
bytes::Bytes
instance via #284The router does a a fair bit of deserialization, filtering, aggregation and re-serializing of JSON objects. Since we currently operate on a dynamic schema, we've been relying on
serde_json::Value
to represent this data internally.After this change, that
Value
type is now replaced with an equivalent type from a newserde_json_bytes
, which acts as an envelope around an underlyingbytes::Bytes
. This allows us to refer to the buffer that contained the JSON data while avoiding the allocation and copying costs on each string for values that are largely unused by the Router directly.This should offer future benefits when implementing — e.g., query de-duplication and caching — since a single buffer will be usable by multiple responses at the same time.
-
Development workflow improvement via #367
Polished away some existing Problems reported by
rust-analyzer
and added troubleshooting instructions to our documentation. -
Removed unnecessary
Arc
fromPreparedQuery
'sexecute
via #328...and followed up with #367
-
Bumped/upstream improvements to
test_span
via #359...and
apollographql/test-span#11
upstreamInternally, this is just a version bump to the Router, but it required upstream changes to the
test-span
crate. The bump brings new filtering abilities and adjusts the verbosity of spans tracing levels, and removes non-determinism from tests.
v0.1.0-alpha.3
🚀🌒 Public alpha release
✨ Features
-
Trace sampling #228: Tracing each request can be expensive. The router now supports sampling, which allows us to only send a fraction of the received requests.
-
Health check #54
🐛 Fixes
-
Schema parse errors #136: The router wouldn't display what went wrong when parsing an invalid Schema. It now displays exactly where a the parsing error occured, and why.
-
Various tracing and telemetry fixes #237: The router wouldn't display what went wrong when parsing an invalid Schema. It now displays exactly where a the parsing error occured, and why.
-
Query variables validation #62: Now that we have a schema parsing feature, we can validate the variables and their types against the schemas and queries.