Search code examples
scalasprayspray-routing

Spray - deserializing optional query parameter


From spray.io documentation page:

color extract value of parameter “color” as String

color.? extract optional value of parameter “color” as Option[String]

amount.as[Int] extract value of parameter “amount” as Int, you need a matching Deserializer in scope for that to work (see also Unmarshalling)

So how can I parse optional Int value? Something like amount.?.as[Int] doesn't seem to work.


Solution

  • You can see the details here: https://github.com/spray/spray/blob/76ab89c25ce6d4ff2c4b286efcc92ee02ced6eff/spray-routing/src/main/scala/spray/routing/directives/NameReceptacle.scala

    case class NameReceptacle[A](name: String) {
      def as[B] = NameReceptacle[B](name)
      def as[B](deserializer: FSOD[B]) = NameDeserializerReceptacle(name, deserializer)
      def ? = as[Option[A]]
      def ?[B](default: B) = NameDefaultReceptacle(name, default)
      def ![B](requiredValue: B) = RequiredValueReceptacle(name, requiredValue)
    }
    

    The straightforward syntax would be

    "amount".as[Option[Int]]
    

    Unfortunately there is no syntactic sugar to create a NameRecaptable for an option type directly, but you can do it in two steps:

    "amount".as[Int].as[Option[Int]]
    

    ? is an alias for NameRecaptable[A].as[Option[A]], so you can use the following code (note the postfix operator syntax):

    "amount".as[Int]?