fix(demand-control): don't multiply field-level @cost by list size#9779
fix(demand-control): don't multiply field-level @cost by list size#9779carodewig wants to merge 2 commits into
Conversation
… by list size An explicit @cost on a list-returning field was being multiplied by the field's estimated/actual list size instead of charged once per call, because cost_directive_from_field merged field-level and type-level @cost into a single value before scoring. CostDirective now tracks its origin (CostDirectiveOrigin::Field vs ::Type) so score_field and score_response_field can charge field-level weight once and only scale type-level/default weight by list size. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@carodewig, please consider creating a changeset entry in |
✅ Docs preview readyThe preview is ready to be viewed. View the preview File Changes 0 new, 1 changed, 0 removedBuild ID: 2d40349464cc48c40e8bd9a3 URL: https://www.apollographql.com/docs/deploy-preview/2d40349464cc48c40e8bd9a3
|
What
ROUTER-1978: a
@costdirective declared directly on a list-returning field was being multiplied by the field's estimated/actual list size instead of charged once per call.apollo-federation/src/link/cost_spec_definition.rs:CostDirectivenow carries aCostDirectiveOrigin(FieldorType) recording whether a resolved@costweight was declared directly on the field/argument, or inherited by falling back to@coston the referenced type.apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs:score_field(estimated cost) andscore_response_field(actual cost) now charge a field-level@costonce per call. Type-level@costand the default per-kind weights are unaffected and continue to scale with list size, as in the existing documented examples.field_level_cost_with_list_size_testsmodule instatic_cost.rscovering: field-level@cost+@listSizewith a free scalar child, the same with a weighted child, and a type-level-only case that guards against inverting the fix. New schema fixtures for these live incustom_cost_schema.graphql.docs/source/routing/security/demand-control.mdxwith a "Field-level cost vs. type-level cost" section and worked example.Verified
cargo fmt --all --check -- --config "imports_granularity=Item,group_imports=StdExternalCrate"passedcargo clippy -p apollo-federation -p apollo-router --all-targets -- -D warningspassedCHANGELOG.mdnot modifiedbackward_compatibility_tests