1

I'd like to unmarshall a query param in akka http like the following:

name=jim&age=30&dob=11-20-1990

import java.time.LocalDate
import akka.http.scaladsl.marshalling.ToResponseMarshallable
import akka.http.scaladsl.server._
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.server.Directives.{complete, _}
...
parameters(('name.as[String].?, 'age.as[Int].?, 'dob.as[String].?)) { (name, age, dob) =>

I can unmarshall everything ok as String or Int, but I'd like to unmarsall the dob as a java.util.LocalDate, like this:

parameters(('name.as[String].?, 'age.as[Int].?, 'dob.as[LocalDate].?)) { (name, age, dob) =>

However, I'm getting the following error:

[error] routes/Router.scala:141: type mismatch;
[error]  found   : (akka.http.scaladsl.common.NameOptionReceptacle[Int], akka.http.scaladsl.common.NameOptionReceptacle[Int], akka.http.scaladsl.common.NameOptionReceptacle[java.time.LocalDate])
[error]  required: akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet
[error]             parameters(('$top.as[Int].?, '$skip.as[Int].?, 'modified_date.as[LocalDate].?)) { (top, skip, modifiedDate) =>

I tried adding a custom LocalDate unmarshaller in scope, but I'm still getting the same error:

implicit val LocalDateUnmarshaller = new JsonReader[LocalDate] {

      def read(value: JsValue) = value match {
        case JsString(x) => LocalDate.parse(x)
        case x => throw new RuntimeException(s"Unexpected type %s on parsing of LocalDate type".format(x.getClass.getName))
      }
    }
Rory
  • 798
  • 2
  • 12
  • 37
  • Thanks, this was a duplicate, though I didn't find that question when I was searching – Rory Oct 11 '17 at 08:56

1 Answers1

1

Try this:

object LocalDateUnmarshaller {
  
  import java.time.LocalDate
  import java.time.format.DateTimeFormatter

  implicit val localDateFromStringUnmarshaller: Unmarshaller[String, LocalDate] =
    Unmarshaller.strict[String, LocalDate] { string =>
      val formatter = DateTimeFormatter.ofPattern("yyyy-MMM-dd")
      val date = LocalDate.parse(string, formatter)
      date
    }
  
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Emiliano Martinez
  • 4,073
  • 2
  • 9
  • 19