diff --git a/.changesets/docs_feature_ignoreotherprefixesdocupdate.md b/.changesets/docs_feature_ignoreotherprefixesdocupdate.md deleted file mode 100644 index 30b41dd95d..0000000000 --- a/.changesets/docs_feature_ignoreotherprefixesdocupdate.md +++ /dev/null @@ -1,5 +0,0 @@ -### Update documentation for `ignore_other_prefixes` ([PR #5592](https://github.com/apollographql/router/pull/5592)) - -Update [JWT authentication documentation](https://www.apollographql.com/docs/router/configuration/authn-jwt/) to clarify the behavior of the `ignore_other_prefixes` configuration option. - -By [@andrewmcgivery](https://github.com/andrewmcgivery) in https://github.com/apollographql/router/pull/5592 diff --git a/.changesets/feat_bnjjj_feat_284.md b/.changesets/feat_bnjjj_feat_284.md deleted file mode 100644 index f58a7f6a80..0000000000 --- a/.changesets/feat_bnjjj_feat_284.md +++ /dev/null @@ -1,18 +0,0 @@ -### Add 'subgraph_on_graphql_error' selector for subgraph ([PR #5622](https://github.com/apollographql/router/pull/5622)) - -The router now supports the `subgraph_on_graphql_error` selector for the subgraph service, which it already supported for the router and supergraph services. Subgraph service support enables easier detection of GraphQL errors in response bodies of subgraph requests. - -An example configuration with `subgraph_on_graphql_error` configured: - -```yaml -telemetry: - instrumentation: - instruments: - subgraph: - http.client.request.duration: - attributes: - subgraph.graphql.errors: # attribute containing a boolean set to true if response.errors is not empty - subgraph_on_graphql_error: true -``` - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5622 \ No newline at end of file diff --git a/.changesets/feat_bnjjj_feat_condition_copro.md b/.changesets/feat_bnjjj_feat_condition_copro.md deleted file mode 100644 index d4d588edfc..0000000000 --- a/.changesets/feat_bnjjj_feat_condition_copro.md +++ /dev/null @@ -1,25 +0,0 @@ -### Support conditional coprocessor execution per stage of request lifecycle ([PR #5557](https://github.com/apollographql/router/pull/5557)) - -The router now supports conditional execution of the coprocessor for each stage of the request lifecycle (except for the `Execution` stage). - -To configure, define conditions for a specific stage by using selectors based on headers or context entries. For example, based on a supergraph response you can configure the coprocessor not to execute for any subscription: - - - -```yaml title=router.yaml -coprocessor: - url: http://127.0.0.1:3000 # mandatory URL which is the address of the coprocessor - timeout: 2s # optional timeout (2 seconds in this example). If not set, defaults to 1 second - supergraph: - response: - condition: - not: - eq: - - subscription - - operation_kind: string - body: true -``` - -To learn more, see the documentation about [coprocessor conditions](https://www.apollographql.com/docs/router/customizations/coprocessor/#conditions). - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5557 \ No newline at end of file diff --git a/.changesets/feat_geal_configure_introspection_caching.md b/.changesets/feat_geal_configure_introspection_caching.md deleted file mode 100644 index fe883cac2b..0000000000 --- a/.changesets/feat_geal_configure_introspection_caching.md +++ /dev/null @@ -1,14 +0,0 @@ -### Add option to deactivate introspection response caching ([PR #5583](https://github.com/apollographql/router/pull/5583)) - -The router now supports an option to deactivate introspection response caching. Because the router caches responses as introspection happens in the query planner, cached introspection responses may consume too much of the distributed cache or fill it up. Setting this option prevents introspection responses from filling up the router's distributed cache. - -To deactivate introspection caching, set `supergraph.query_planning.legacy_introspection_caching` to `false`: - - -```yaml -supergraph: - query_planning: - legacy_introspection_caching: false -``` - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5583 \ No newline at end of file diff --git a/.changesets/fix_bnjjj_fix_event_instr_response_context_sel.md b/.changesets/fix_bnjjj_fix_event_instr_response_context_sel.md deleted file mode 100644 index a326ef8f3c..0000000000 --- a/.changesets/fix_bnjjj_fix_event_instr_response_context_sel.md +++ /dev/null @@ -1,26 +0,0 @@ -### Add `response_context` in event selector for `event_*` instruments ([PR #5565](https://github.com/apollographql/router/pull/5565)) - -The router now supports creating custom instruments with a value set to `event_*` and using both a condition executed on an event and the `response_context` selector in attributes. Previous releases didn't support the `response_context` selector in attributes. - -An example configuration: - -```yaml -telemetry: - instrumentation: - instruments: - supergraph: - sf.graphql_router.errors: - value: event_unit - type: counter - unit: count - description: "graphql errors handled by the apollo router" - condition: - eq: - - true - - on_graphql_error: true - attributes: - "operation": - response_context: "operation_name" # This was not working before -``` - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5565 \ No newline at end of file diff --git a/.changesets/fix_bnjjj_fix_rhai_traceid.md b/.changesets/fix_bnjjj_fix_rhai_traceid.md deleted file mode 100644 index d440972712..0000000000 --- a/.changesets/fix_bnjjj_fix_rhai_traceid.md +++ /dev/null @@ -1,7 +0,0 @@ -### Provide valid trace IDs for unsampled traces in Rhai scripts ([PR #5606](https://github.com/apollographql/router/pull/5606)) - -The `traceid()` function in a Rhai script for the router now returns a valid trace ID for all traces. - -Previously, `traceid()` didn't return a trace ID if the trace wasn't selected for sampling. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5606 \ No newline at end of file diff --git a/.changesets/fix_datadog_trace_resource_mapping.md b/.changesets/fix_datadog_trace_resource_mapping.md deleted file mode 100644 index 306a1d0a54..0000000000 --- a/.changesets/fix_datadog_trace_resource_mapping.md +++ /dev/null @@ -1,64 +0,0 @@ -### Fix span names and resource mapping for Datadog trace exporter ([Issue #5282](https://github.com/apollographql/router/issues/5282)) - -> [!NOTE] -> This is an **incremental** improvement, but we expect more improvements in Router v1.52.0 after https://github.com/apollographql/router/pull/5609/ lands. - -The router now uses _static span names_ by default. This change fixes the user experience of the Datadog trace exporter when sending traces with Datadog native configuration. - -The router has two ways of sending traces to Datadog: - -1. The [OpenTelemetry for Datadog](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog/#otlp-configuration) approach (which is the recommended method). This is identified by `otlp` in YAML configuration, and it is *not* impacted by this fix. -2. The ["Datadog native" configuration](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog/#datadog-native-configuration). This is identified by the use of a `datadog:` key in YAML configuration. - -This change fixes a bug in the latter approach that broke some Datadog experiences, such as the "Resources" section of the [Datadog APM Service Catalog](https://docs.datadoghq.com/service_catalog/) page. - -We now use static span names by default, with resource mappings providing additional context when requested, which enables the desired behavior which was not possible before. - -_If for some reason you wish to maintain the existing behavior, you must either update your spans and resource mappings, or keep your spans and instead configure the router to use _dynamic span names_ and disable resource mapping._ - -Enabling resource mapping and fixed span names is configured by the `enable_span_mapping` and `fixed_span_names` options: - -```yaml -telemetry: - exporters: - tracing: - datadog: - enabled: true - # Enables resource mapping, previously disabled by default, but now enabled. - enable_span_mapping: true - # Enables fixed span names, defaults to true. - fixed_span_names: true - - instrumentation: - spans: - mode: spec_compliant -``` - -With `enable_span_mapping` set to `true` (now default), the following resource mappings are applied: - -| OpenTelemetry Span Name | Datadog Span Operation Name | -|-------------------------|-----------------------------| -| `request` | `http.route` | -| `router` | `http.route` | -| `supergraph` | `graphql.operation.name` | -| `query_planning` | `graphql.operation.name` | -| `subgraph` | `subgraph.name` | -| `subgraph_request` | `graphql.operation.name` | -| `http_request` | `http.route` | - -You can override the default resource mappings by specifying the `resource_mapping` configuration: - -```yaml -telemetry: - exporters: - tracing: - datadog: - enabled: true - resource_mapping: - # Use `my.span.attribute` as the resource name for the `router` span - router: "my.span.attribute" -``` - -To learn more, see the [Datadog trace exporter](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog) documentation. - -By [@bnjjj](https://github.com/bnjjj) and [@bryncooke](https://github.com/bryncooke) in https://github.com/apollographql/router/pull/5386 diff --git a/.changesets/fix_error_locations.md b/.changesets/fix_error_locations.md deleted file mode 100644 index 125c004a21..0000000000 --- a/.changesets/fix_error_locations.md +++ /dev/null @@ -1,33 +0,0 @@ -### Gracefully handle subgraph response with `-1` values inside error locations ([PR #5633](https://github.com/apollographql/router/pull/5633)) - -This router now gracefully handles responses that contain invalid "`-1`" positional values for error locations in queries by ignoring those invalid locations. - -This change resolves the problem of GraphQL Java and GraphQL Kotlin using `{ "line": -1, "column": -1 }` values if they can't determine an error's location in a query, but the GraphQL specification [requires both `line` and `column` to be positive numbers](https://spec.graphql.org/draft/#sel-GAPHRPFCCaCGX5zM). - -As an example, a subgraph can respond with invalid error locations: -```json -{ - "data": { "topProducts": null }, - "errors": [{ - "message":"Some error on subgraph", - "locations": [ - { "line": -1, "column": -1 }, - ], - "path":["topProducts"] - }] -} -``` - -With this change, the router returns a response that ignores the invalid locations: - -```json -{ - "data": { "topProducts": null }, - "errors": [{ - "message":"Some error on subgraph", - "path":["topProducts"] - }] -} -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5633 \ No newline at end of file diff --git a/.changesets/fix_garypen_router_411_batching_entity_caching.md b/.changesets/fix_garypen_router_411_batching_entity_caching.md deleted file mode 100644 index 70fb1ccbcf..0000000000 --- a/.changesets/fix_garypen_router_411_batching_entity_caching.md +++ /dev/null @@ -1,5 +0,0 @@ -### Allow query batching and entity caching to work together ([PR #5598](https://github.com/apollographql/router/pull/5598)) - -The router now supports entity caching and subgraph batching to run simultaneously. Specifically, this change updates entity caching to ignore a subgraph request if the request is part of a batch. - -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/5598 \ No newline at end of file diff --git a/.changesets/fix_timeout_and_rate_limit_error.md b/.changesets/fix_timeout_and_rate_limit_error.md deleted file mode 100644 index d0bdac9d3b..0000000000 --- a/.changesets/fix_timeout_and_rate_limit_error.md +++ /dev/null @@ -1,7 +0,0 @@ -### Return request timeout and rate limited error responses as structured errors ([PR #5578](https://github.com/apollographql/router/pull/5578)) - -The router now returns request timeout errors (`408 Request Timeout`) and request rate limited errors (`429 Too Many Requests`) as structured GraphQL errors (for example, `{"errors": [...]}`). Previously, the router returned these as plaintext errors to clients. - -Both types of errors are properly tracked in telemetry, including the `apollo_router_graphql_error_total` metric. - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5578 \ No newline at end of file diff --git a/.config/nextest.toml b/.config/nextest.toml index df8bab66e6..cff09c8ef6 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -1,3 +1,92 @@ +[[profile.default.overrides]] +# These are known flaky tests according to the test flakiness report provided +# in CircleCI insights, based on the `dev` branch: +# +# https://app.circleci.com/insights/github/apollographql/router/workflows/ci_checks/tests +# +# We will retry these tests up to 2 additional times. Retry counts are recorded. +# Items on this list should be prioritized to get improved and removed from this +# list at the time they are fixed. +# +# Frankly, it may be best to just retry all tests in the apollo-router::integration_tests +# module, as they have a high failure rate, in general. +retries = 2 +filter = ''' + ( binary_id(=apollo-router) & test(=axum_factory::axum_http_server_factory::tests::request_cancel_log) ) +or ( binary_id(=apollo-router) & test(=axum_factory::axum_http_server_factory::tests::request_cancel_no_log) ) +or ( binary_id(=apollo-router) & test(=notification::tests::it_test_ttl) ) +or ( binary_id(=apollo-router) & test(=plugins::telemetry::metrics::apollo::test::apollo_metrics_enabled) ) +or ( binary_id(=apollo-router) & test(=plugins::telemetry::tests::it_test_prometheus_metrics) ) +or ( binary_id(=apollo-router) & test(=services::subgraph_service::tests::test_subgraph_service_websocket_with_error) ) +or ( binary_id(=apollo-router) & test(=uplink::license_stream::test::license_expander_claim_pause_claim) ) +or ( binary_id(=apollo-router) & test(=uplink::persisted_queries_manifest_stream::test::integration_test) ) +or ( binary_id(=apollo-router-benchmarks) & test(=tests::test) ) +or ( binary_id(=apollo-router::apollo_otel_traces) & test(=test_batch_send_header) ) +or ( binary_id(=apollo-router::apollo_otel_traces) & test(=test_batch_trace_id) ) +or ( binary_id(=apollo-router::apollo_otel_traces) & test(=test_condition_if) ) +or ( binary_id(=apollo-router::apollo_otel_traces) & test(=test_trace_id) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=non_defer) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_batch_stats) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_client_name) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_client_version) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_condition_if) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_send_header) ) +or ( binary_id(=apollo-router::apollo_reports) & test(=test_trace_id) ) +or ( binary_id(=apollo-router::integration_tests) & test(=api_schema_hides_field) ) +or ( binary_id(=apollo-router::integration_tests) & test(=automated_persisted_queries) ) +or ( binary_id(=apollo-router::integration_tests) & test(=defer_default_variable) ) +or ( binary_id(=apollo-router::integration_tests) & test(=defer_path) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_batches_with_errors_in_multi_graph) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_batches_with_errors_in_single_graph) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_cancelled_by_coprocessor) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_cancelled_by_rhai) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_indefinite_timeouts) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_short_timeouts) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_single_invalid_graphql) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_single_request_cancelled_by_coprocessor) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_handles_single_request_cancelled_by_rhai) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_supports_multi_subgraph_batching) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::batching::it_supports_single_subgraph_batching) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::coprocessor::test_error_not_propagated_to_client) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_incompatible_query_order) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_invalid_file_order) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_invalid_multipart_order) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_upload_without_file) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_with_file_count_limits) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_with_file_size_limit) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_fails_with_no_boundary_in_multipart) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::file_upload::it_uploads_to_multiple_subgraphs) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::lifecycle::test_graceful_shutdown) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::lifecycle::test_happy) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::lifecycle::test_reload_config_valid) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::lifecycle::test_reload_config_with_broken_plugin) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::lifecycle::test_reload_config_with_broken_plugin_recovery) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::apq) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::connection_failure_blocks_startup) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::entity_cache) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::query_planner_redis_update_defer) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::query_planner_redis_update_query_fragments) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::query_planner_redis_update_reuse_query_fragments) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::redis::test::connection_failure_blocks_startup) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::telemetry::jaeger::test_decimal_trace_id) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::telemetry::logging::test_json) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::telemetry::logging::test_json_sampler_off) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::telemetry::logging::test_text_sampler_off) ) +or ( binary_id(=apollo-router::integration_tests) & test(=integration::telemetry::metrics::test_subgraph_auth_metrics) ) +or ( binary_id(=apollo-router::samples) & test(=/enterprise/entity-cache/invalidation) ) +or ( binary_id(=apollo-router::samples) & test(=/enterprise/entity-cache/invalidation-subgraph) ) +or ( binary_id(=apollo-router::samples) & test(=/enterprise/entity-cache/invalidation-subgraph-type) ) +or ( binary_id(=apollo-router::samples) & test(=/enterprise/query-planning-redis) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_dependent_fetch_failure) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_list) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_list_of_lists) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_no_typenames) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_type_mismatch) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_union) ) +or ( binary_id(=apollo-router::set_context) & test(=test_set_context_unrelated_fetch_failure) ) +''' + [profile.ci] # Print out output for failing tests as soon as they fail, and also at the end # of the run (for easy scrollability). diff --git a/CHANGELOG.md b/CHANGELOG.md index b45c3d2af4..de369468ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,230 @@ All notable changes to Router will be documented in this file. This project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec/v2.0.0.html). +# [1.51.0] - 2024-07-16 + +## 🚀 Features + +### Support conditional coprocessor execution per stage of request lifecycle ([PR #5557](https://github.com/apollographql/router/pull/5557)) + +The router now supports conditional execution of the coprocessor for each stage of the request lifecycle (except for the `Execution` stage). + +To configure, define conditions for a specific stage by using selectors based on headers or context entries. For example, based on a supergraph response you can configure the coprocessor not to execute for any subscription: + + + +```yaml title=router.yaml +coprocessor: + url: http://127.0.0.1:3000 # mandatory URL which is the address of the coprocessor + timeout: 2s # optional timeout (2 seconds in this example). If not set, defaults to 1 second + supergraph: + response: + condition: + not: + eq: + - subscription + - operation_kind: string + body: true +``` + +To learn more, see the documentation about [coprocessor conditions](https://www.apollographql.com/docs/router/customizations/coprocessor/#conditions). + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5557 + +### Add option to deactivate introspection response caching ([PR #5583](https://github.com/apollographql/router/pull/5583)) + +The router now supports an option to deactivate introspection response caching. Because the router caches responses as introspection happens in the query planner, cached introspection responses may consume too much of the distributed cache or fill it up. Setting this option prevents introspection responses from filling up the router's distributed cache. + +To deactivate introspection caching, set `supergraph.query_planning.legacy_introspection_caching` to `false`: + + +```yaml +supergraph: + query_planning: + legacy_introspection_caching: false +``` + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5583 + +### Add 'subgraph_on_graphql_error' selector for subgraph ([PR #5622](https://github.com/apollographql/router/pull/5622)) + +The router now supports the `subgraph_on_graphql_error` selector for the subgraph service, which it already supported for the router and supergraph services. Subgraph service support enables easier detection of GraphQL errors in response bodies of subgraph requests. + +An example configuration with `subgraph_on_graphql_error` configured: + +```yaml +telemetry: + instrumentation: + instruments: + subgraph: + http.client.request.duration: + attributes: + subgraph.graphql.errors: # attribute containing a boolean set to true if response.errors is not empty + subgraph_on_graphql_error: true +``` + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5622 + +## 🐛 Fixes + +### Add `response_context` in event selector for `event_*` instruments ([PR #5565](https://github.com/apollographql/router/pull/5565)) + +The router now supports creating custom instruments with a value set to `event_*` and using both a condition executed on an event and the `response_context` selector in attributes. Previous releases didn't support the `response_context` selector in attributes. + +An example configuration: + +```yaml +telemetry: + instrumentation: + instruments: + supergraph: + sf.graphql_router.errors: + value: event_unit + type: counter + unit: count + description: "graphql errors handled by the apollo router" + condition: + eq: + - true + - on_graphql_error: true + attributes: + "operation": + response_context: "operation_name" # This was not working before +``` + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5565 + +### Provide valid trace IDs for unsampled traces in Rhai scripts ([PR #5606](https://github.com/apollographql/router/pull/5606)) + +The `traceid()` function in a Rhai script for the router now returns a valid trace ID for all traces. + +Previously, `traceid()` didn't return a trace ID if the trace wasn't selected for sampling. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5606 + +### Allow query batching and entity caching to work together ([PR #5598](https://github.com/apollographql/router/pull/5598)) + +The router now supports entity caching and subgraph batching to run simultaneously. Specifically, this change updates entity caching to ignore a subgraph request if the request is part of a batch. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/5598 + +### Gracefully handle subgraph response with `-1` values inside error locations ([PR #5633](https://github.com/apollographql/router/pull/5633)) + +This router now gracefully handles responses that contain invalid "`-1`" positional values for error locations in queries by ignoring those invalid locations. + +This change resolves the problem of GraphQL Java and GraphQL Kotlin using `{ "line": -1, "column": -1 }` values if they can't determine an error's location in a query, but the GraphQL specification [requires both `line` and `column` to be positive numbers](https://spec.graphql.org/draft/#sel-GAPHRPFCCaCGX5zM). + +As an example, a subgraph can respond with invalid error locations: +```json +{ + "data": { "topProducts": null }, + "errors": [{ + "message":"Some error on subgraph", + "locations": [ + { "line": -1, "column": -1 }, + ], + "path":["topProducts"] + }] +} +``` + +With this change, the router returns a response that ignores the invalid locations: + +```json +{ + "data": { "topProducts": null }, + "errors": [{ + "message":"Some error on subgraph", + "path":["topProducts"] + }] +} +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5633 + +### Return request timeout and rate limited error responses as structured errors ([PR #5578](https://github.com/apollographql/router/pull/5578)) + +The router now returns request timeout errors (`408 Request Timeout`) and request rate limited errors (`429 Too Many Requests`) as structured GraphQL errors (for example, `{"errors": [...]}`). Previously, the router returned these as plaintext errors to clients. + +Both types of errors are properly tracked in telemetry, including the `apollo_router_graphql_error_total` metric. + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5578 + +### Fix span names and resource mapping for Datadog trace exporter ([Issue #5282](https://github.com/apollographql/router/issues/5282)) + +> [!NOTE] +> This is an **incremental** improvement, but we expect more improvements in Router v1.52.0 after https://github.com/apollographql/router/pull/5609/ lands. + +The router now uses _static span names_ by default. This change fixes the user experience of the Datadog trace exporter when sending traces with Datadog native configuration. + +The router has two ways of sending traces to Datadog: + +1. The [OpenTelemetry for Datadog](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog/#otlp-configuration) approach (which is the recommended method). This is identified by `otlp` in YAML configuration, and it is *not* impacted by this fix. +2. The ["Datadog native" configuration](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog/#datadog-native-configuration). This is identified by the use of a `datadog:` key in YAML configuration. + +This change fixes a bug in the latter approach that broke some Datadog experiences, such as the "Resources" section of the [Datadog APM Service Catalog](https://docs.datadoghq.com/service_catalog/) page. + +We now use static span names by default, with resource mappings providing additional context when requested, which enables the desired behavior which was not possible before. + +_If for some reason you wish to maintain the existing behavior, you must either update your spans and resource mappings, or keep your spans and instead configure the router to use _dynamic span names_ and disable resource mapping._ + +Enabling resource mapping and fixed span names is configured by the `enable_span_mapping` and `fixed_span_names` options: + +```yaml +telemetry: + exporters: + tracing: + datadog: + enabled: true + # Enables resource mapping, previously disabled by default, but now enabled. + enable_span_mapping: true + # Enables fixed span names, defaults to true. + fixed_span_names: true + + instrumentation: + spans: + mode: spec_compliant +``` + +With `enable_span_mapping` set to `true` (now default), the following resource mappings are applied: + +| OpenTelemetry Span Name | Datadog Span Operation Name | +|-------------------------|-----------------------------| +| `request` | `http.route` | +| `router` | `http.route` | +| `supergraph` | `graphql.operation.name` | +| `query_planning` | `graphql.operation.name` | +| `subgraph` | `subgraph.name` | +| `subgraph_request` | `graphql.operation.name` | +| `http_request` | `http.route` | + +You can override the default resource mappings by specifying the `resource_mapping` configuration: + +```yaml +telemetry: + exporters: + tracing: + datadog: + enabled: true + resource_mapping: + # Use `my.span.attribute` as the resource name for the `router` span + router: "my.span.attribute" +``` + +To learn more, see the [Datadog trace exporter](https://www.apollographql.com/docs/router/configuration/telemetry/exporters/tracing/datadog) documentation. + +By [@bnjjj](https://github.com/bnjjj) and [@bryncooke](https://github.com/bryncooke) in https://github.com/apollographql/router/pull/5386 + +## 📚 Documentation + +### Update documentation for `ignore_other_prefixes` ([PR #5592](https://github.com/apollographql/router/pull/5592)) + +Update [JWT authentication documentation](https://www.apollographql.com/docs/router/configuration/authn-jwt/) to clarify the behavior of the `ignore_other_prefixes` configuration option. + +By [@andrewmcgivery](https://github.com/andrewmcgivery) in https://github.com/apollographql/router/pull/5592 + + + # [1.50.0] - 2024-07-02 ## 🚀 Features diff --git a/Cargo.lock b/Cargo.lock index eef116f7b9..0884397df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -421,7 +421,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.51.0-rc.0" +version = "1.51.0" dependencies = [ "apollo-compiler", "derive_more", @@ -467,7 +467,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.51.0-rc.0" +version = "1.51.0" dependencies = [ "access-json", "anyhow", @@ -631,7 +631,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.51.0-rc.0" +version = "1.51.0" dependencies = [ "apollo-parser", "apollo-router", @@ -647,7 +647,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.51.0-rc.0" +version = "1.51.0" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index 120f6df656..49868b2989 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.51.0-rc.0" +version = "1.51.0" authors = ["The Apollo GraphQL Contributors"] edition = "2021" description = "Apollo Federation" diff --git a/apollo-router-benchmarks/Cargo.toml b/apollo-router-benchmarks/Cargo.toml index e8cd4de196..c2acf8a5c8 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.51.0-rc.0" +version = "1.51.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/Cargo.toml b/apollo-router-scaffold/Cargo.toml index c343dc949a..aa62f1b73d 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.51.0-rc.0" +version = "1.51.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 5e55c3e608..4733b6c87d 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.toml @@ -22,7 +22,7 @@ apollo-router = { path ="{{integration_test}}apollo-router" } apollo-router = { git="https://github.com/apollographql/router.git", branch="{{branch}}" } {{else}} # Note if you update these dependencies then also update xtask/Cargo.toml -apollo-router = "1.51.0-rc.0" +apollo-router = "1.51.0" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index 868f439be2..d5c86be60b 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml @@ -13,7 +13,7 @@ apollo-router-scaffold = { path ="{{integration_test}}apollo-router-scaffold" } {{#if branch}} apollo-router-scaffold = { git="https://github.com/apollographql/router.git", branch="{{branch}}" } {{else}} -apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.51.0-rc.0" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.51.0" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 6a3ddc9c34..c0875539eb 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.51.0-rc.0" +version = "1.51.0" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -68,7 +68,7 @@ askama = "0.12.1" access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.51.0-rc.0" } +apollo-federation = { path = "../apollo-federation", version = "=1.51.0" } arc-swap = "1.6.0" async-channel = "1.9.0" async-compression = { version = "0.4.6", features = [ diff --git a/dockerfiles/tracing/docker-compose.datadog.yml b/dockerfiles/tracing/docker-compose.datadog.yml index a9a90fdd5a..d353c22089 100644 --- a/dockerfiles/tracing/docker-compose.datadog.yml +++ b/dockerfiles/tracing/docker-compose.datadog.yml @@ -3,7 +3,7 @@ services: apollo-router: container_name: apollo-router - image: ghcr.io/apollographql/router:v1.51.0-rc.0 + image: ghcr.io/apollographql/router:v1.51.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/datadog.router.yaml:/etc/config/configuration.yaml diff --git a/dockerfiles/tracing/docker-compose.jaeger.yml b/dockerfiles/tracing/docker-compose.jaeger.yml index 4186454392..56d42a866f 100644 --- a/dockerfiles/tracing/docker-compose.jaeger.yml +++ b/dockerfiles/tracing/docker-compose.jaeger.yml @@ -4,7 +4,7 @@ services: apollo-router: container_name: apollo-router #build: ./router - image: ghcr.io/apollographql/router:v1.51.0-rc.0 + image: ghcr.io/apollographql/router:v1.51.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/jaeger.router.yaml:/etc/config/configuration.yaml diff --git a/dockerfiles/tracing/docker-compose.zipkin.yml b/dockerfiles/tracing/docker-compose.zipkin.yml index e32d0f3a92..5b26c558d0 100644 --- a/dockerfiles/tracing/docker-compose.zipkin.yml +++ b/dockerfiles/tracing/docker-compose.zipkin.yml @@ -4,7 +4,7 @@ services: apollo-router: container_name: apollo-router build: ./router - image: ghcr.io/apollographql/router:v1.51.0-rc.0 + image: ghcr.io/apollographql/router:v1.51.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/zipkin.router.yaml:/etc/config/configuration.yaml diff --git a/helm/chart/router/Chart.yaml b/helm/chart/router/Chart.yaml index e16ede05fe..3e98c25b35 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: 1.51.0-rc.0 +version: 1.51.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: "v1.51.0-rc.0" +appVersion: "v1.51.0" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index be9a36f32a..9282d0e4f4 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: 1.51.0-rc.0](https://img.shields.io/badge/Version-1.51.0--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.51.0-rc.0](https://img.shields.io/badge/AppVersion-v1.51.0--rc.0-informational?style=flat-square) +![Version: 1.51.0](https://img.shields.io/badge/Version-1.51.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.51.0](https://img.shields.io/badge/AppVersion-v1.51.0-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.51.0-rc.0 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.51.0 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.51.0-rc.0 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.51.0-rc.0 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.51.0 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/scripts/install.sh b/scripts/install.sh index 47b35295bc..f2e7e7a0f4 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -11,7 +11,7 @@ BINARY_DOWNLOAD_PREFIX="https://github.com/apollographql/router/releases/downloa # Router version defined in apollo-router's Cargo.toml # Note: Change this line manually during the release steps. -PACKAGE_VERSION="v1.51.0-rc.0" +PACKAGE_VERSION="v1.51.0" download_binary() { downloader --check