Describe the bug
For the ID scalar type, the GraphQL specification defines coercion of input values as:
https://spec.graphql.org/October2021/#sec-ID.Input-Coercion
When expected as an input type, any string (such as "4") or integer (such as 4 or -4) input value should be coerced to ID as appropriate for the ID formats a given GraphQL service expects. Any other input value, including float input values (such as 4.0), must raise a request error indicating an incorrect type.
Apollo Router 1.30.0 implements this as "validate like an input value of type String or Int". The latter is limited to i32:
https://spec.graphql.org/October2021/#sec-Int.Input-Coercion
When expected as an input type, only integer input values are accepted. All other input values, including strings with numeric content, must raise a request error indicating an incorrect type. If the integer input value represents a value less than -2^31 or greater than or equal to 2^31, a request error should be raised.
However no such range is specified for ID. In theory the Router could be made to support integer IDs of arbitrary size. In practice it’s probably unwise to go beyond 53 bits, in case a client or subgraph represents integer like JavaScript does, as floating point with a 53-bit mantissa. Still, it’s easy enough to make the Router support up to i64 here.
To Reproduce
Steps to reproduce the behavior:
- Create a
/tmp/router.yaml file that contains {}
- Run
cargo run -- -c /tmp/router.yaml -s examples/graphql/supergraph.graphql
- In another terminal, run:
curl -s --request POST \
--header 'content-type: application/json' \
--url 'http://127.0.0.1:4000' \
--data '{"variables": {"var": 2147483648}, "query":"query Q($var: ID!) { topProducts { name reviewsForAuthor(authorID: $var) { id } } }"}'
Expected behavior
The response contains data and no error.
Output
{"errors":[{"message":"invalid type for variable: 'var'","extensions":{"name":"var","code":"VALIDATION_INVALID_TYPE_VARIABLE"}}]}
Additional context
Manually tested fix:
--- a/apollo-router/src/spec/field_type.rs
+++ b/apollo-router/src/spec/field_type.rs
@@ -110,7 +110,7 @@ fn validate_input_value(
// In practice it seems Int works too
(hir::Type::Named { name, .. }, Value::String(_)) if name == "ID" => Ok(()),
(hir::Type::Named { name, .. }, maybe_int) if name == "ID" => {
- if maybe_int == &Value::Null || maybe_int.is_valid_int_input() {
+ if maybe_int == &Value::Null || maybe_int.as_i64().is_some() {
Ok(())
} else {
Err(InvalidValue)
Still needs an automatic test, ideally one checking that 9007199254740993 (2^53 + 1) is passed through to the subgraph without being rounded.
Describe the bug
For the
IDscalar type, the GraphQL specification defines coercion of input values as:https://spec.graphql.org/October2021/#sec-ID.Input-Coercion
Apollo Router 1.30.0 implements this as "validate like an input value of type
StringorInt". The latter is limited toi32:https://spec.graphql.org/October2021/#sec-Int.Input-Coercion
However no such range is specified for
ID. In theory the Router could be made to support integer IDs of arbitrary size. In practice it’s probably unwise to go beyond 53 bits, in case a client or subgraph represents integer like JavaScript does, as floating point with a 53-bit mantissa. Still, it’s easy enough to make the Router support up toi64here.To Reproduce
Steps to reproduce the behavior:
/tmp/router.yamlfile that contains{}cargo run -- -c /tmp/router.yaml -s examples/graphql/supergraph.graphqlExpected behavior
The response contains data and no error.
Output
{"errors":[{"message":"invalid type for variable: 'var'","extensions":{"name":"var","code":"VALIDATION_INVALID_TYPE_VARIABLE"}}]}Additional context
Manually tested fix:
Still needs an automatic test, ideally one checking that 9007199254740993 (2^53 + 1) is passed through to the subgraph without being rounded.