diff --git a/src/context.rs b/src/context.rs index 216b5f42..cf8ad15d 100644 --- a/src/context.rs +++ b/src/context.rs @@ -424,6 +424,16 @@ impl<'a, T> ContextBase<'a, T> { } else if let Some(default) = &def.default_value { return Ok(default.clone_inner()); } + match def.var_type.deref() { + &async_graphql_parser::query::Type::Named(_) + | &async_graphql_parser::query::Type::List(_) => { + // Nullable types can default to null when not given. + return Ok(Value::Null); + } + &async_graphql_parser::query::Type::NonNull(_) => { + // Strict types can not. + } + } } Err(QueryError::VarNotDefined { var_name: name.to_string(), diff --git a/tests/variables.rs b/tests/variables.rs index f25e7a49..600076cb 100644 --- a/tests/variables.rs +++ b/tests/variables.rs @@ -71,6 +71,69 @@ pub async fn test_variable_default_value() { ); } +#[async_std::test] +pub async fn test_variable_no_value() { + struct QueryRoot; + + #[Object] + impl QueryRoot { + pub async fn int_val(&self, value: Option) -> i32 { + value.unwrap_or(10) + } + } + + let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription); + let query = QueryBuilder::new( + r#" + query QueryWithVariables($intVal: Int) { + intVal(value: $intVal) + } + "#, + ) + .variables(Variables::parse_from_json(serde_json::json!({})).unwrap()); + let resp = query.execute(&schema).await.unwrap(); + assert_eq!( + resp.data, + serde_json::json!({ + "intVal": 10, + }) + ); +} + +#[async_std::test] +pub async fn test_variable_null() { + struct QueryRoot; + + #[Object] + impl QueryRoot { + pub async fn int_val(&self, value: Option) -> i32 { + value.unwrap_or(10) + } + } + + let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription); + let query = QueryBuilder::new( + r#" + query QueryWithVariables($intVal: Int) { + intVal(value: $intVal) + } + "#, + ) + .variables( + Variables::parse_from_json(serde_json::json!({ + "intVal": null, + })) + .unwrap(), + ); + let resp = query.execute(&schema).await.unwrap(); + assert_eq!( + resp.data, + serde_json::json!({ + "intVal": 10, + }) + ); +} + #[async_std::test] pub async fn test_variable_in_input_object() { #[InputObject]