-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Call scalar coerceUserInput before coerceOutput #993
base: main
Are you sure you want to change the base?
Call scalar coerceUserInput before coerceOutput #993
Conversation
e779fcd
to
f17e172
Compare
val corcedInput = scalar | ||
.coerceUserInput(value) | ||
// Do we need a specific exepction here? | ||
.fold(e => throw new ValidationError(Vector(e), exceptionHandler), identity) | ||
val coerced = scalar.coerceOutput(corcedInput, marshaller.capabilities) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing an exception here because the whole block is protected by try/catch
@@ -34,6 +34,7 @@ class ResolverBasedAstSchemaBuilderSpec extends AnyWordSpec with Matchers with F | |||
"UUID", | |||
coerceOutput = (v, _) => v.toString, | |||
coerceUserInput = { | |||
case uuid: UUID => Right(uuid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I try to understand:
coerceUserInput
is now called twice:
- the first time to parse the user input as
String
into aUUID
- the second time to confirm that a
UUID
is a valid value
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it is not called, twice, but I have spent a bit of time looking at Apollo implementation, and I think, I would just need to change the scalars rather than Sangria.
In Apollo the scalar are represented by 3 functions:
serialize
it is the same ascoerceOutput
, it coerces the scalar to a JSON representationparseLiteral
it is the same ascoerceInput
that is bit misleading, it basically coerces and hardcoded value into the scalar typeparseValue
it is the same ascoerceUserInput
that basically coerces the values coming from the users via not hardcoded variables.
When you have an untyped underlying model, like JSON, the serialize
function should take care also of parsing the type from the underlying model.
I will investigate more about that and maybe drop this PR in favour of a documentation one.
This PR investigates a solution for #991
The scalar are always input coerced before coerced for output. This also mean that for any
scalarType: ScalarType[T]
,scalarType.coerceUserInput
must accept anyT
and return it as-is (It is already the case for all the builtin Scalars).The coercion happens in two places, the default field resolver, and the FutureResolver, that is basically the base resolver. I could not find a better place to do it, probably something in between the input unmarshaller and the resolver would be the best place. Unfortunately, the unmarshaller does not receive any information about the ScalarType, so it can only leverage the underlying model.