We’re going to explore how we can use a default value for a value class in Sangria.

This builds on the previous blog post about Sangria.

If I put a default on an input argument that’s a Value class Like I do for Color here:

Field(
    "paintCat",
    Cat.gqlType,
    arguments = List(
      Argument("cat", Cat.gqlInputType),
      Argument("color", Color.gqlType, Color("black")),
      Argument("speed", Speed.gqlType)
    ),
    resolve = c => {
      paintCat(c.arg[Cat]("cat"), c.arg[Color]("color"), c.arg[Speed]("speed"))
    }
)
case class Color(underlying: String) extends AnyVal
object Color {
  implicit val circeDecoder: Decoder[Color] = SangriaUtils.circeValueClassDecoder(apply)
  implicit val gqlType: ScalarAlias[Color, String] = SangriaUtils.gqlAliasType(apply, _.underlying)
}

Then I get this message

Invalid default value of argument 'color' in field 'paintCat' defined in output type 'Mutation'. Field 'Mutation.paintCat.[color]' has wrong value: Invalid value.
at sangria.schema.SchemaValidationRule$.validateWithException(SchemaValidationRule.scala:54)
at sangria.schema.Schema.<init>(Schema.scala:1397)
at GraphQL.executeGraphQLQuery(GraphQL.scala:43)
at GraphQL.$anonfun$endpoint$1(GraphQL.scala:29)
at akka.http.scaladsl.server.directives.RouteDirectives.$anonfun$complete$1(RouteDirectives.scala:51)
etc

To make this work, I have to also add a Circe encoder for Color:

implicit val circeEncoder: Encoder[Color] = Encoder.instance[Color](c => Json.fromString(c.underlying))

Now everything works fine.

shadow-left