Context
I have setup like so:
case class Foo(
option_enum_vector_field: Option[Vector[Bar]] // Bar is complicated object which can't be easily expressed with sangria default scalars, but can be created by using Bar.apply(enum_str: String)
)
// My expected GraphQL input type for Bar
implicit val FooEnumFieldType = EnumType(
"FooEnumFieldType",
Some("description"),
List(
EnumValue("high", value = "high"),
EnumValue("medium", value = "medium"),
EnumValue("low", value = "low")
)
)
val FooType = ObjectType(
"FooType",
"description",
fields[Unit, Foo](
Field("option_enum_vector_field", OptionType(ListType(FooEnumFieldType)), resolve = _.value.???),
)
)
In resolve = ctx => ctx.value.option_enum_vector_field
is what the result should be so it expects Option[Vector[Bar]]
type. Because I put OptionType(ListType(FooEnumFieldType))
as my GraphQL type there is a mismatch between types and compiler is swearing at me.
What I do not understand is where and how I should tell Sangria how to go from FooEnumFieldType
GraphQL input to Bar
type by taking enum value from client and doing Bar.apply("high")
for example.
Questions
- How to define mappings from GraphQL enum types to Scala types in sangria?
- How to get values passed from client in resolve function?
CodePudding user response:
You need a ObjectType
for Bar
to allow sangria to use it as an output type. The simplest method would be to derive the object type for Bar
automatically.
implicit val BarType =
deriveObjectType[Unit, Bar]()
This requires sangria to be able to convert all the elements of Bar
so if that is not possible then a custom object may be required.
implicit val BarType: ObjectType[Unit, Bar] = ObjectType(
"Bar",
"Bar",
fields[Unit, Bar](
Field("id", IDType, resolve = _.value.id),
// other fields
)
)
Sangria use this implicit
value to convert Bar
values to BarType
values which, in turn, can be used to generate the JSON output as required. ObjectType
is a typeclass that can be used in other sangria methods to process objects of type Bar
.
Finally the "option_enum_vector_field" field needs to have the appropriate type:
Field("option_enum_vector_field", OptionType(ListType(BarType)), resolve = _.value.option_enum_vector_field),
[ If you are actually implementing a mutation
then you need to create an instance of InputObjectType
that performs the reverse mapping ]