diff --git a/.changesets/docs_jr_add_all_in_one_container_docs.md b/.changesets/docs_jr_add_all_in_one_container_docs.md deleted file mode 100644 index 9f40900b87..0000000000 --- a/.changesets/docs_jr_add_all_in_one_container_docs.md +++ /dev/null @@ -1,6 +0,0 @@ -### Add the Apollo Runtime Container To The Deployment Documentation - -As per the title, now that we have the Apollo Runtime Container we need to add that to the set of options for -deployment. - -By [@jonathanrainer](https://github.com/jonathanrainer) in https://github.com/apollographql/router/pull/7668 diff --git a/.changesets/docs_lambertjosh_readd_graph_docs.md b/.changesets/docs_lambertjosh_readd_graph_docs.md deleted file mode 100644 index bb158f1742..0000000000 --- a/.changesets/docs_lambertjosh_readd_graph_docs.md +++ /dev/null @@ -1,5 +0,0 @@ -### Add back the graph artifact documentation for the containers [PR #7752](hhttps://github.com/apollographql/router/pull/7752) - -Adds back accidentally overwritten docs which occurred in PR 7734. The missing commit added graph artifact usage information. - -By [lambertjosh](https://github.com/lambertjosh) in https://github.com/apollographql/router/pull/7752 \ No newline at end of file diff --git a/.changesets/docs_lambertjosh_update_docker_docs_runtime.md b/.changesets/docs_lambertjosh_update_docker_docs_runtime.md deleted file mode 100644 index 767ce9ee6c..0000000000 --- a/.changesets/docs_lambertjosh_update_docker_docs_runtime.md +++ /dev/null @@ -1,5 +0,0 @@ -### Updates the Docker deployment instructions to use the Apollo Runtime container [PR #7734](https://github.com/apollographql/router/pull/7734) - -With the release of the MCP Server, a method to easily deploy Apollo's runtime services was needed. The Apollo Runtime container was designed to address this need, which includes both the Router and MCP Servers in a single Docker container. This PR updates the Router deployment Docker instructions to use this new container. - -By [lambertjosh](https://github.com/lambertjosh) in https://github.com/apollographql/router/pull/7734 \ No newline at end of file diff --git a/.changesets/docs_lrlna_schema_load_duration.md b/.changesets/docs_lrlna_schema_load_duration.md deleted file mode 100644 index 1f6142f197..0000000000 --- a/.changesets/docs_lrlna_schema_load_duration.md +++ /dev/null @@ -1,5 +0,0 @@ -### Fix incorrect reference to `apollo.router.schema.load.duration` metric in the docs([PR #7582](https://github.com/apollographql/router/pull/7582)) - -The [in-memory cache documentation](https://www.apollographql.com/docs/graphos/routing/performance/caching/in-memory#cache-warm-up) was referencing an incorrect metric to track schema load times. Previously it was referred to as `apollo.router.schema.loading.time`, where the metric being emitted by the router since router@2.0.0 is `apollo.router.schema.load.duration`. This is now fixed in the docs. - -By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/7582 \ No newline at end of file diff --git a/.changesets/feat_caroline_consistent_on_error.md b/.changesets/feat_caroline_consistent_on_error.md deleted file mode 100644 index 9e3b679021..0000000000 --- a/.changesets/feat_caroline_consistent_on_error.md +++ /dev/null @@ -1,5 +0,0 @@ -### Align `on_graphql_error` selector return values with `subgraph_on_graphql_error` ([PR #7676](https://github.com/apollographql/router/pull/7676)) - -The `on_graphql_error` selector will now return `true` or `false`, in alignment with the `subgraph_on_graphql_error` selector. Previously, the selector would return `true` or `None`. - -By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7676 diff --git a/.changesets/feat_caroline_low_priority_warmup.md b/.changesets/feat_caroline_low_priority_warmup.md deleted file mode 100644 index 5bd6f3b858..0000000000 --- a/.changesets/feat_caroline_low_priority_warmup.md +++ /dev/null @@ -1,18 +0,0 @@ -### De-prioritize warm-up process query parsing and planning ([PR #7223](https://github.com/apollographql/router/pull/7223)) - -The router warms up its query planning cache after a schema or configuration change. This change decreases the priority -of warm up tasks in the compute job queue, to reduce the impact of warmup on serving requests. - -This change adds new values to the `job.type` dimension of the following metrics: -- `apollo.router.compute_jobs.duration` - A histogram of time spent in the compute pipeline by the job, including the queue and query planning. - - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) - - `job.outcome`: (`executed_ok`, `executed_error`, `channel_error`, `rejected_queue_full`, `abandoned`) -- `apollo.router.compute_jobs.queue.wait.duration` - A histogram of time spent in the compute queue by the job. - - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) -- `apollo.router.compute_jobs.execution.duration` - A histogram of time spent to execute job (excludes time spent in the queue). - - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) -- `apollo.router.compute_jobs.active_jobs` - A gauge of the number of compute jobs being processed in parallel. - - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) - - -By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7223 diff --git a/.changesets/feat_glasser_pq_error_include_extensions.md b/.changesets/feat_glasser_pq_error_include_extensions.md deleted file mode 100644 index 881bf124dc..0000000000 --- a/.changesets/feat_glasser_pq_error_include_extensions.md +++ /dev/null @@ -1,5 +0,0 @@ -### pq: include operation name in `PERSISTED_QUERY_NOT_IN_LIST` error ([PR #7768](https://github.com/apollographql/router/pull/7768)) - -When persisted query safelisting is enabled and a request has an unknown PQ ID, the GraphQL error now has the extension field `operation_name` containing the GraphQL operation name (if provided explicitly in the request). Note that this only applies to the `PERSISTED_QUERY_NOT_IN_LIST` error returned when manifest-based PQs are enabled, APQs are disabled, and the request contains an operation ID that is not in the list. - -By [@glasser](https://github.com/glasser) in https://github.com/apollographql/router/pull/7768 \ No newline at end of file diff --git a/.changesets/feat_zelda_add_jwt_audience_validation.md b/.changesets/feat_zelda_add_jwt_audience_validation.md deleted file mode 100644 index 679b0a0d47..0000000000 --- a/.changesets/feat_zelda_add_jwt_audience_validation.md +++ /dev/null @@ -1,37 +0,0 @@ -### add support for JWT audience validation ([PR #7578](https://github.com/apollographql/router/pull/7578)) - -Adds support for validating the `aud` (audience) claim in JWTs. This allows the router to ensure that the JWT is intended -for the specific audience it is being used with, enhancing security by preventing token misuse across different audiences. - -#### Example Usage - -```yaml title="router.yaml" -authentication: - router: - jwt: - jwks: # This key is required. - - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json - issuers: # optional list of issuers - - https://issuer.one - - https://issuer.two - audiences: # optional list of audiences - - https://my.api - - https://my.other.api - poll_interval: - headers: # optional list of static headers added to the HTTP request to the JWKS URL - - name: User-Agent - value: router - # These keys are optional. Default values are shown. - header_name: Authorization - header_value_prefix: Bearer - on_error: Error - # array of alternative token sources - sources: - - type: header - name: X-Authorization - value_prefix: Bearer - - type: cookie - name: authz -``` - -By [@Velfi](https://github.com/Velfi) in https://github.com/apollographql/router/pull/7578 diff --git a/.changesets/feat_zelda_feature_cooperative_cancellation.md b/.changesets/feat_zelda_feature_cooperative_cancellation.md deleted file mode 100644 index 0490986c7e..0000000000 --- a/.changesets/feat_zelda_feature_cooperative_cancellation.md +++ /dev/null @@ -1,22 +0,0 @@ -## Cooperative Cancellation for Query Planning - -This release introduces cooperative cancellation support for query planning operations. This feature allows the router -to gracefully handle query planning timeouts and cancellations, improving resource utilization. -Metrics are emitted for cooperative cancellation: - -- Records the "outcome" of query planning on the `apollo.router.query_planning.plan.duration` metric. -- Records the "outcome" of query planning on the `query_planning` span. - -### Example - -Configuring a timeout in Measure Mode: -```yaml -supergraph: - query_planning: - experimental_cooperative_cancellation: - enabled: true - mode: measure - timeout: 1s -``` - -By [@Velfi](https://github.com/Velfi) in https://github.com/apollographql/router/pull/7604 diff --git a/.changesets/fix_bnjjj_add_operation_name_subscription_metric.md b/.changesets/fix_bnjjj_add_operation_name_subscription_metric.md deleted file mode 100644 index 7bdae49ded..0000000000 --- a/.changesets/fix_bnjjj_add_operation_name_subscription_metric.md +++ /dev/null @@ -1,5 +0,0 @@ -### Add graphql.operation.name label to apollo.router.opened.subscriptions counter ([PR #7606](https://github.com/apollographql/router/pull/7606)) - -`apollo.router.opened.subscriptions` metric contains `graphql.operation.name` label to know exactly which subscription is still opened. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7606 \ No newline at end of file diff --git a/.changesets/fix_bnjjj_fix_coprocessor_subscription.md b/.changesets/fix_bnjjj_fix_coprocessor_subscription.md deleted file mode 100644 index 3dff4ff0db..0000000000 --- a/.changesets/fix_bnjjj_fix_coprocessor_subscription.md +++ /dev/null @@ -1,5 +0,0 @@ -### Set a valid GraphQL response for websocket handshake response ([PR #7680](https://github.com/apollographql/router/pull/7680)) - -Since this [PR](https://github.com/apollographql/router/pull/7141) we added more checks on graphql response returned by coprocessors to be compliant with GraphQL specs. When it's a subscription using websocket it was not returning any data and so was not a correct GraphQL response payload. This is a fix to always return valid GraphQL response when doing the websocket handshake. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7680 \ No newline at end of file diff --git a/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md b/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md deleted file mode 100644 index 1c8fb8d235..0000000000 --- a/.changesets/fix_bnjjj_fix_telemetry_prom_resource.md +++ /dev/null @@ -1,19 +0,0 @@ -### Telemetry: export properly resources on metrics configured on prometheus ([PR #7394](https://github.com/apollographql/router/pull/7394)) - -When configuring `telemetry.exporters.metrics.common.resource` to globally add labels on metrics, these labels were not exported to every metrics on prometheus. This can now be done if you set `resource_selector` to `all` (default is `none`). - -```yaml -telemetry: - exporters: - metrics: - common: - resource: - "test-resource": "test" - prometheus: - enabled: true - resource_selector: all # This will add resources on every metrics -``` - -This only occurred with Prometheus and not OTLP. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7394 diff --git a/.changesets/fix_caroline_coprocessor_on_graphql_error.md b/.changesets/fix_caroline_coprocessor_on_graphql_error.md deleted file mode 100644 index f4e97f21e5..0000000000 --- a/.changesets/fix_caroline_coprocessor_on_graphql_error.md +++ /dev/null @@ -1,5 +0,0 @@ -### Fix `on_graphql_error` selector ([PR #7669](https://github.com/apollographql/router/pull/7669)) - -The `on_graphql_error` selector will now correctly fire on the supergraph stage; previously it only worked on the router stage. - -By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7669 \ No newline at end of file diff --git a/.changesets/fix_garypen_fix_otlp_http_metrics.md b/.changesets/fix_garypen_fix_otlp_http_metrics.md deleted file mode 100644 index 3f20f4d6a3..0000000000 --- a/.changesets/fix_garypen_fix_otlp_http_metrics.md +++ /dev/null @@ -1,30 +0,0 @@ -### Fix otlp metric export when using http protocol ([PR #7595](https://github.com/apollographql/router/pull/7595)) - -We updated the router dependency for opentelemetry when we released router 2.0. - -The opentelemetry dependency changed how it processed endpoints (destinations for metrics and traces) and this was not detected until now. - -The router wasn't setting the path correctly, so exporting metrics over http was not working for the default endpoint. Exporting metrics via gRPC was not impacted. Neither were traces. - -We have fixed our interactions with the dependency and improved our testing to make sure this does not occur again. - -The router now supports setting standard OTEL environment variables for endpoints. - -There is a known problem when using environment variables to configure endpoints for the http protocol with un-encrypted traffic, i.e. TLS not configured. If any of: - -OTEL_EXPORTER_OTLP_ENDPOINT -OTEL_EXPORTER_OTLP_METRICS_ENDPOINT -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - -are set, then you will see log messages which look like: - -``` -2025-06-06T15:12:47.992144Z ERROR OpenTelemetry metric error occurred: Metrics exporter otlp failed with the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) })) -2025-06-06T15:12:47.992763Z ERROR OpenTelemetry trace error occurred: Exporter otlp encountered the following error(s): the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) })) -``` - -The traces and metrics are processed and delivered correctly to the specified endpoint regardless of this message. - -Note: For more details about the issue with non-TLS traffic: https://github.com/open-telemetry/opentelemetry-collector/issues/10952 - -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/7595 diff --git a/.changesets/fix_garypen_http_ext_clone_works_properly.md b/.changesets/fix_garypen_http_ext_clone_works_properly.md deleted file mode 100644 index eab7837188..0000000000 --- a/.changesets/fix_garypen_http_ext_clone_works_properly.md +++ /dev/null @@ -1,13 +0,0 @@ -### Ensure that file uploads work correctly with Rhai scripts ([PR #7559](https://github.com/apollographql/router/pull/7559)) - -If a Rhai script was invoked during File Upload processing, then the "Content-Type" of the Request was not preserved correctly. This would cause a File Upload to fail. - -The error message would be something like: - -``` -"message": "invalid multipart request: Content-Type is not multipart/form-data", -``` - -This is now fixed. - -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/7559 diff --git a/.changesets/fix_invalid_variable_error_message.md b/.changesets/fix_invalid_variable_error_message.md deleted file mode 100644 index 69fb8772c2..0000000000 --- a/.changesets/fix_invalid_variable_error_message.md +++ /dev/null @@ -1,10 +0,0 @@ -### Improve error message for invalid variables ([Issue #2984](https://github.com/apollographql/router/issues/2984)) - -When a variable in a GraphQL request is missing or contains an invalid value, the router now returns more useful error messages. Example: - -```diff --invalid type for variable: 'x' -+invalid input value at x.coordinates[0].longitude: found JSON null for GraphQL Float! -``` - -By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/7567 diff --git a/.changesets/fix_mantel_headband_iced_move.md b/.changesets/fix_mantel_headband_iced_move.md deleted file mode 100644 index 66289dfbc2..0000000000 --- a/.changesets/fix_mantel_headband_iced_move.md +++ /dev/null @@ -1,5 +0,0 @@ -### Fix issue loading SigV4 config ([PR #7726](https://github.com/apollographql/router/pull/7726)) - -Fixed an issue introduced in Router 2.3.0 where some SigV4 configurations would fail to start. - -By [@dylan-apollo](https://github.com/dylan-apollo) in https://github.com/apollographql/router/pull/7726 diff --git a/.changesets/fix_qp_forbid_unknown_links.md b/.changesets/fix_qp_forbid_unknown_links.md deleted file mode 100644 index d6b87f740a..0000000000 --- a/.changesets/fix_qp_forbid_unknown_links.md +++ /dev/null @@ -1,6 +0,0 @@ -### Fixed native query planner regression not forbidding unknown spec links - -The legacy JavaScript query planner forbids any usage of unknown `@link` specs in supergraph schemas with either `EXECUTION` or `SECURITY` value set for the `for` argument (aka, the spec's "purpose"). This behavior had not been ported to the native query planner previously. This PR implements the expected behavior in the native query planner. - -By [@duckki](https://github.com/duckki) in https://github.com/apollographql/router/pull/7587 - diff --git a/.changesets/fix_query_plan_defer_invalid_root_type.md b/.changesets/fix_query_plan_defer_invalid_root_type.md deleted file mode 100644 index b2d2cebac7..0000000000 --- a/.changesets/fix_query_plan_defer_invalid_root_type.md +++ /dev/null @@ -1,5 +0,0 @@ -### (Query Planner) Fix invalid type condition in `@defer` fetch - -The query planner could add an inline spread conditioned on the `Query` type in deferred subgraph fetch queries. Such a query would be invalid in the subgraph when the subgraph schema renamed the root query type. This fix removes the root type condition from all subgraph queries, so that they stay valid even when root types were renamed. - -By [@duckki](https://github.com/duckki) in https://github.com/apollographql/router/pull/7580 diff --git a/.changesets/maint_extended_errors_telemetry.md b/.changesets/maint_extended_errors_telemetry.md deleted file mode 100644 index 47554a0801..0000000000 --- a/.changesets/maint_extended_errors_telemetry.md +++ /dev/null @@ -1,3 +0,0 @@ -### Measure `preview_extended_error_metrics` in Apollo config telemetry. ([PR #7597](https://github.com/apollographql/router/pull/7597)) - -By [@timbotnik](https://github.com/timbotnik) in https://github.com/apollographql/router/pull/7597 diff --git a/CHANGELOG.md b/CHANGELOG.md index e44359cf98..a695017f2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,230 @@ This project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec/v2.0.0.html). +# [2.4.0] - 2025-06-30 + +## πŸš€ Features + +### Support JWT audience (`aud`) validation ([PR #7578](https://github.com/apollographql/router/pull/7578)) + +The router now supports JWT audience (`aud`) validation. This allows the router to ensure that the JWT is intended +for the specific audience it is being used with, enhancing security by preventing token misuse across different audiences. + +The following sample configuration will validate the JWT's `aud` claim against the specified audiences and ensure a match with either `https://my.api` or `https://my.other.api`. If the `aud` claim does not match either of those configured audiences, the router will reject the request. + +```yaml +authentication: + router: + jwt: + jwks: # This key is required. + - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json + issuers: # optional list of issuers + - https://issuer.one + - https://issuer.two + audiences: # optional list of audiences + - https://my.api + - https://my.other.api + poll_interval: + headers: # optional list of static headers added to the HTTP request to the JWKS URL + - name: User-Agent + value: router + # These keys are optional. Default values are shown. + header_name: Authorization + header_value_prefix: Bearer + on_error: Error + # array of alternative token sources + sources: + - type: header + name: X-Authorization + value_prefix: Bearer + - type: cookie + name: authz +``` + +By [@Velfi](https://github.com/Velfi) in https://github.com/apollographql/router/pull/7578 + +### Prioritize existing requests over query parsing and planning during "warm up" ([PR #7223](https://github.com/apollographql/router/pull/7223)) + +The router warms up its query planning cache during a hot reload. This change decreases the priority +of warm up tasks in the compute job queue to reduce the impact of warmup on serving requests. + +This change adds new values to the `job.type` dimension of the following metrics: +- `apollo.router.compute_jobs.duration` - A histogram of time spent in the compute pipeline by the job, including the queue and query planning. + - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) + - `job.outcome`: (`executed_ok`, `executed_error`, `channel_error`, `rejected_queue_full`, `abandoned`) +- `apollo.router.compute_jobs.queue.wait.duration` - A histogram of time spent in the compute queue by the job. + - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) +- `apollo.router.compute_jobs.execution.duration` - A histogram of time spent to execute job (excludes time spent in the queue). + - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) +- `apollo.router.compute_jobs.active_jobs` - A gauge of the number of compute jobs being processed in parallel. + - `job.type`: (`query_planning`, `query_parsing`, `introspection`, **`query_planning_warmup`, `query_parsing_warmup`**) + +By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7223 + +### Persisted queries: include operation name in `PERSISTED_QUERY_NOT_IN_LIST` error for debuggability ([PR #7768](https://github.com/apollographql/router/pull/7768)) + +When persisted query safelisting is enabled and a request has an unknown PQ ID, the GraphQL error now has the extension field `operation_name` containing the GraphQL operation name (if provided explicitly in the request). Note that this only applies to the `PERSISTED_QUERY_NOT_IN_LIST` error returned when manifest-based PQs are enabled, APQs are disabled, and the request contains an operation ID that is not in the list. + +By [@glasser](https://github.com/glasser) in https://github.com/apollographql/router/pull/7768 + +## Introduce cooperative cancellation for query planning + +The cooperative cancellation feature allows the router to gracefully handle query planning timeouts and cancellations, improving resource utilization. + +The `mode` can be set to `measure` or `enforce`. We recommend starting with `measure`. In `measure` mode, the router will measure the time taken for query planning and emit metrics accordingly. In `enforce` mode, the router will cancel query planning operations that exceed the specified timeout. + +To observe this behavior, the router telemetry has been updated: + +- Add an `outcome` attribute to the `apollo.router.query_planning.plan.duration` metric +- Add an `outcome` attribute to the `query_planning` span + +Below is a sample configuration to configure cooperative cancellation in measure mode: + +```yaml +supergraph: + query_planning: + experimental_cooperative_cancellation: + enabled: true + mode: measure + timeout: 1s +``` + +By [@Velfi](https://github.com/Velfi) in https://github.com/apollographql/router/pull/7604 + +## πŸ› Fixes + +### Align `on_graphql_error` selector with `subgraph_on_graphql_error` ([PR #7676](https://github.com/apollographql/router/pull/7676)) + +The `on_graphql_error` selector will now return `true` or `false`, in alignment with the `subgraph_on_graphql_error` selector. Previously, the selector would return `true` or `None`. + +By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7676 + +### Return valid GraphQL response when performing a websocket handshake ([PR #7680](https://github.com/apollographql/router/pull/7680)) + +[PR #7141](https://github.com/apollographql/router/pull/7141) added checks on GraphQL responses returned from coprocessors to ensure compliance with GraphQL specifications. This surfaced an issue where subscription responses over websockets could omit the required `data` field during the handshake, resulting in invalid GraphQL response payloads. All websocket subscription responses will now return a valid GraphQL response when doing the websocket handshake. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7680 + +### Fix SigV4 configuration handling ([PR #7726](https://github.com/apollographql/router/pull/7726)) + +Fixed an issue introduced in Router 2.3.0 where some SigV4 configurations would fail to start, preventing communication with SigV4-enabled services. + +By [@dylan-apollo](https://github.com/dylan-apollo) in https://github.com/apollographql/router/pull/7726 + +### Improve error message for invalid variables ([Issue #2984](https://github.com/apollographql/router/issues/2984)) + +When a variable in a GraphQL request is missing or contains an invalid value, the router now returns more useful error messages. Example: + +```diff +-invalid type for variable: 'x' ++invalid input value at x.coordinates[0].longitude: found JSON null for GraphQL Float! +``` + +By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/7567 + +### Support exporting resources on all Prometheus metrics ([PR #7394](https://github.com/apollographql/router/pull/7394)) + +By default, the Prometheus metrics exporter will only export resources as `target_info` metrics, not inline on every metric. Now, you can add resources to every metric by setting `resource_selector` to `all` (default is `none`). + +```yaml +telemetry: + exporters: + metrics: + common: + resource: + "test-resource": "test" + prometheus: + enabled: true + resource_selector: all # This will add resources on every metrics +``` + +Note: this change only affects Prometheus, not OTLP. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7394 + +### Forbid unknown `@link` directives for supergraph schemas where `purpose` is `EXECUTION` or `SECURITY` + +The legacy JavaScript query planner forbid any usage of unknown `@link` specs in supergraph schemas with either `EXECUTION` or `SECURITY` value set for the `for` argument (aka, the spec's "purpose"). This behavior had not been ported to the native query planner previously. This PR implements the expected behavior in the native query planner. + +By [@duckki](https://github.com/duckki) in https://github.com/apollographql/router/pull/7587 + +### Supergraph stage correctly receives `on_graphql_error` selector ([PR #7669](https://github.com/apollographql/router/pull/7669)) + +The `on_graphql_error` selector will now correctly fire on the supergraph stage; previously it only worked on the router stage. + +By [@carodewig](https://github.com/carodewig) in https://github.com/apollographql/router/pull/7669 + +### Invalid type condition in `@defer` fetch + +The query planner was adding an inline spread (`...`) conditioned on the `Query` type in deferred subgraph fetch queries. Such a query would be invalid in the subgraph when the subgraph schema renamed the root `query` type to somethhing other than `Query`. The fix removes the root type condition from all subgraph queries, so that they stay valid even when root types are renamed. + +By [@duckki](https://github.com/duckki) in https://github.com/apollographql/router/pull/7580 + +### Preserve `content-type` for file uploads when Rhai scripts are in use ([PR #7559](https://github.com/apollographql/router/pull/7559)) + +If a Rhai script was invoked during file upload processing, then the "Content-Type" of the request was not preserved correctly. This would cause a file upload to fail. + +The error message would be something like: + +``` +"message": "invalid multipart request: Content-Type is not multipart/form-data", +``` + +This issue has now been fixed. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/7559 + +### Improve OTLP metric HTTP endpoint behavior ([PR #7595](https://github.com/apollographql/router/pull/7595)) + +We made substantial updates to OpenTelemetry in router 2.0, but didn't catch that OpenTelemetry changed how it processed "endpoints" (destinations for metrics and traces) until now. + +With the undetected change, the router wasn't setting the path correctly, resulting in failure to export metrics over HTTP when using the "default" endpoint. **Neither metrics via gRPC nor traces were impacted**. + +We have fixed our interactions with the dependency and improved our testing to make sure this does not occur again. Additionally, the router now supports setting standard OpenTelemetry environment variables for endpoints. + +There is still a known problem when using environment variables to configure endpoints for the HTTP protocol when transmitting to an un-encrypted endpoint (i.e., TLS not configured). This affects the following environment variables: + +- `OTEL_EXPORTER_OTLP_ENDPOINT` +- `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` +- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` + +When these environment variables are set to insecure hosts, messages will appear in the logs indicating an error, but **the metrics and traces will still be sent correctly**: + +``` +2025-06-06T15:12:47.992144Z ERROR OpenTelemetry metric error occurred: Metrics exporter otlp failed with the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) })) +2025-06-06T15:12:47.992763Z ERROR OpenTelemetry trace error occurred: Exporter otlp encountered the following error(s): the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) })) +``` + +This is tracked upstream at https://github.com/open-telemetry/opentelemetry-collector/issues/10952. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/7595 + +### Add `graphql.operation.name` attribute to `apollo.router.opened.subscriptions` counter ([PR #7606](https://github.com/apollographql/router/pull/7606)) + +The `apollo.router.opened.subscriptions` metric has an `graphql.operation.name` attribute applied to identify the named operation of open subscriptions. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/7606 + +## πŸ›  Maintenance + +### Measure `preview_extended_error_metrics` in Apollo config telemetry ([PR #7597](https://github.com/apollographql/router/pull/7597)) + +By [@timbotnik](https://github.com/timbotnik) in https://github.com/apollographql/router/pull/7597 + +## πŸ“š Documentation + +### Document Apollo Runtime Container deployment ([PR #7734](https://github.com/apollographql/router/pull/7734) and [PR #7668](https://github.com/apollographql/router/pull/7668)) + +The Apollo Runtime Container is now included in our documentation for deployment options. It also includes instructions for running Apollo Router with the Apollo MCP Server. + +By [@jonathanrainer](https://github.com/jonathanrainer) and [@lambertjosh](https://github.com/lambertjosh) in https://github.com/apollographql/router/pull/7734 and https://github.com/apollographql/router/pull/7668 + +### Fix incorrect reference to `apollo.router.schema.load.duration` ([PR #7582](https://github.com/apollographql/router/pull/7582)) + +The [in-memory cache documentation](https://www.apollographql.com/docs/graphos/routing/performance/caching/in-memory#cache-warm-up) was referencing an incorrect metric to track schema load times. Previously it was referred to as `apollo.router.schema.loading.time`, whereas the metric being emitted by the router since v2.0.0 is actually `apollo.router.schema.load.duration`. This is now fixed. + +By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/7582 + # [2.3.0] - 2025-06-02 ## πŸš€ Features diff --git a/Cargo.lock b/Cargo.lock index 7cbc43f473..e3fcf82093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "2.4.0-rc.0" +version = "2.4.0" dependencies = [ "apollo-compiler", "apollo-federation", @@ -261,7 +261,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "2.4.0-rc.0" +version = "2.4.0" dependencies = [ "ahash", "anyhow", @@ -436,7 +436,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "2.4.0-rc.0" +version = "2.4.0" dependencies = [ "apollo-parser", "apollo-router", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index 8d32210bab..61eb802229 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "2.4.0-rc.0" +version = "2.4.0" authors = ["The Apollo GraphQL Contributors"] edition = "2024" description = "Apollo Federation" diff --git a/apollo-router-benchmarks/Cargo.toml b/apollo-router-benchmarks/Cargo.toml index c7552be6e7..5611999599 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "2.4.0-rc.0" +version = "2.4.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 317f67bc5a..ef94748bd4 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "2.4.0-rc.0" +version = "2.4.0" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -58,7 +58,7 @@ snapshot = ["axum-server", "serde_regex"] [dependencies] anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=2.4.0-rc.0" } +apollo-federation = { path = "../apollo-federation", version = "=2.4.0" } async-compression = { version = "0.4.6", features = [ "tokio", "brotli", diff --git a/docs/shared/k8s-manual-config.mdx b/docs/shared/k8s-manual-config.mdx index e7127c745a..e8684b9984 100644 --- a/docs/shared/k8s-manual-config.mdx +++ b/docs/shared/k8s-manual-config.mdx @@ -6,10 +6,10 @@ kind: ServiceAccount metadata: name: release-name-router labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm --- # Source: router/templates/secret.yaml @@ -18,10 +18,10 @@ kind: Secret metadata: name: "release-name-router" labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm data: managedFederationApiKey: "UkVEQUNURUQ=" @@ -32,10 +32,10 @@ kind: ConfigMap metadata: name: release-name-router labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm data: configuration.yaml: | @@ -55,10 +55,10 @@ kind: Service metadata: name: release-name-router labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm spec: type: ClusterIP @@ -81,10 +81,10 @@ kind: Deployment metadata: name: release-name-router labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm @@ -103,10 +103,10 @@ spec: annotations: kubectl.kubernetes.io/default-container: router labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm spec: serviceAccountName: release-name-router @@ -117,7 +117,7 @@ spec: - name: router securityContext: {} - image: "ghcr.io/apollographql/router:v2.4.0-rc.0" + image: "ghcr.io/apollographql/router:v2.4.0" imagePullPolicy: IfNotPresent args: - --hot-reload @@ -171,10 +171,10 @@ kind: Pod metadata: name: "release-name-router-test-connection" labels: - helm.sh/chart: router-2.4.0-rc.0 + helm.sh/chart: router-2.4.0 app.kubernetes.io/name: router app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "v2.4.0-rc.0" + app.kubernetes.io/version: "v2.4.0" app.kubernetes.io/managed-by: Helm annotations: "helm.sh/hook": test diff --git a/helm/chart/router/Chart.yaml b/helm/chart/router/Chart.yaml index b0da427230..5eb8792bdc 100644 --- a/helm/chart/router/Chart.yaml +++ b/helm/chart/router/Chart.yaml @@ -20,10 +20,10 @@ type: application # so it matches the shape of our release process and release automation. # By proxy of that decision, this version uses SemVer 2.0.0, though the prefix # of "v" is not included. -version: 2.4.0-rc.0 +version: 2.4.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "v2.4.0-rc.0" +appVersion: "v2.4.0" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 7c46a729b0..fc4fb39ffb 100644 --- a/helm/chart/router/README.md +++ b/helm/chart/router/README.md @@ -2,7 +2,7 @@ [router](https://github.com/apollographql/router) Rust Graph Routing runtime for Apollo Federation -![Version: 2.4.0-rc.0](https://img.shields.io/badge/Version-2.4.0--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.4.0-rc.0](https://img.shields.io/badge/AppVersion-v2.4.0--rc.0-informational?style=flat-square) +![Version: 2.4.0](https://img.shields.io/badge/Version-2.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.4.0](https://img.shields.io/badge/AppVersion-v2.4.0-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 2.4.0-rc.0 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 2.4.0 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 2.4.0-rc.0 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 2.4.0-rc.0 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 2.4.0 --values my-values.yaml ``` _See [configuration](#configuration) below._ @@ -99,4 +99,4 @@ helm show values oci://ghcr.io/apollographql/helm-charts/router | virtualservice.enabled | bool | `false` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.2](https://github.com/norwoodj/helm-docs/releases/v1.11.2) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/licenses.html b/licenses.html index 424ccebf84..6388b8e274 100644 --- a/licenses.html +++ b/licenses.html @@ -45,7 +45,7 @@

Third Party Licenses

Overview of licenses:

  • Apache License 2.0 (469)
  • -
  • MIT License (147)
  • +
  • MIT License (148)
  • Unicode License v3 (20)
  • BSD 3-Clause "New" or "Revised" License (9)
  • ISC License (7)
  • @@ -64,19 +64,12 @@

    All license text:

    Apache License 2.0

    Used by:

    @@ -265,7 +258,6 @@ 

    Used by:

  • pin-project-lite
  • pin-project
  • portable-atomic-util
  • -
  • portable-atomic
  • sync_wrapper
  • time-core
  • time-macros
  • @@ -5787,8 +5779,6 @@

    Used by:

  • ghost
  • itoa
  • libc
  • -
  • linkme-impl
  • -
  • linkme
  • paste
  • prettyplease
  • proc-macro2
  • @@ -9945,7 +9935,6 @@

    Used by:

    Apache License 2.0

    Used by:

      -
    • docker_credential
    • rand
    • rand
    • rand_chacha
    • @@ -12655,7 +12644,15 @@

      Apache License 2.0

      Used by:

      • apollo-compiler
      • +
      • aws-config
      • +
      • aws-runtime
      • +
      • aws-smithy-http-client
      • +
      • aws-smithy-json
      • +
      • aws-smithy-runtime-api
      • +
      • aws-smithy-types
      • +
      • aws-smithy-xml
      • chrono
      • +
      • docker_credential
      • dunce
      • graphql-introspection-query
      • graphql_client
      • @@ -12663,9 +12660,12 @@

        Used by:

      • graphql_query_derive
      • http-serde
      • ident_case
      • +
      • linkme-impl
      • +
      • linkme
      • num-cmp
      • objc2-core-foundation
      • objc2-io-kit
      • +
      • portable-atomic
      • rhai_codegen
      • siphasher
      • try_match_inner
      • @@ -13567,18 +13567,18 @@

        Used by:

        URL: https://www.elastic.co/licensing/elastic-license -## Acceptance +Acceptance By using the software, you agree to all of the terms and conditions below. -## Copyright License +Copyright License The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below. -## Limitations +Limitations You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of @@ -13592,7 +13592,7 @@

        Used by:

        of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law. -## Patents +Patents The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for @@ -13605,7 +13605,7 @@

        Used by:

        such a claim, your patent license ends immediately for work on behalf of your company. -## Notices +Notices You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. @@ -13618,7 +13618,7 @@

        Used by:

        These terms do not imply any licenses other than those expressly granted in these terms. -## Termination +Termination If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you @@ -13628,34 +13628,34 @@

        Used by:

        reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently. -## No Liability +No Liability -*As far as the law allows, the software comes as is, without any warranty or +As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of -legal claim.* +legal claim. -## Definitions +Definitions -The **licensor** is the entity offering these terms, and the **software** is the +The licensor is the entity offering these terms, and the software is the software the licensor makes available under these terms, including any portion of it. -**you** refers to the individual or entity agreeing to these terms. +you refers to the individual or entity agreeing to these terms. -**your company** is any legal entity, sole proprietorship, or other kind of +your company is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that -organization. **control** means ownership of substantially all the assets of an +organization. control means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -**your licenses** are all the licenses granted to you for the software under +your licenses are all the licenses granted to you for the software under these terms. -**use** means anything you do with the software requiring one of your licenses. +use means anything you do with the software requiring one of your licenses. -**trademark** means trademarks, service marks, and similar rights. +trademark means trademarks, service marks, and similar rights.
  • @@ -15619,11 +15619,20 @@

    Used by:

    Copyright (c) <year> <copyright holders> -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE.
  • @@ -16528,6 +16537,7 @@

    Used by:

  • aho-corasick
  • byteorder
  • globset
  • +
  • jiff
  • memchr
  • regex-automata
  • same-file
  • diff --git a/scripts/install.sh b/scripts/install.sh index e2e3e49a6a..f803ef4d88 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -11,7 +11,7 @@ BINARY_DOWNLOAD_PREFIX="${APOLLO_ROUTER_BINARY_DOWNLOAD_PREFIX:="https://github. # Router version defined in apollo-router's Cargo.toml # Note: Change this line manually during the release steps. -PACKAGE_VERSION="v2.4.0-rc.0" +PACKAGE_VERSION="v2.4.0" download_binary() { downloader --check