5

My spray json support looks like this

object MarshallingSupport extends SprayJsonSupport {
  implicit def json4sFormats: Formats = DefaultFormats
}

And in my route I want to map the request to a dto

object Main extends App with AppConfig with BaseService with MainActorSystem {

  val processor = system.actorOf(Props(), "processorActor")
  val view = system.actorOf(Props(), "processorActor")

  override protected implicit val executor: ExecutionContext = system.dispatcher
  override protected val log: LoggingAdapter = Logging(system, getClass)
  override protected implicit val materializer: ActorMaterializer = ActorMaterializer()

  Http().bindAndHandle(routes(processor, view), httpInterface, httpPort)
}

trait BaseServiceRoute {
  protected implicit def executor: ExecutionContext
  protected implicit def materializer: ActorMaterializer
  protected def log: LoggingAdapter
}

trait MainActorSystem {
  implicit val system = ActorSystem("booking")
}

final case class CalculatePriceForRangeDto(unitId: Int, from: Long, to: Long)

trait PriceServiceRoute extends BaseServiceRoute {

  implicit val timeout = Timeout(30 seconds)

  import com.example.crudapi.utils.MarshallingSupport._

  def customersRoute(command: ActorRef, query: ActorRef) = pathPrefix("price") {
    post {
      path("calculate") {
        decodeRequest {
          entity(as[CalculatePriceForRangeDto]) {
            priceForRange => onComplete((query ? CalculatePriceForRange(

but I'm getting

Error:(32, 20) could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[com.example.crudapi.http.routes.CalculatePriceForRangeDto]
      entity(as[CalculatePriceForRangeDto]) {
               ^

Have seen all related SO questions but nothing solved my issue. Strange part is that I tried Typesafe template akka-dddd-cqrs and it works, same code.

Am I missing something with implicit context? Any ideas of what could it be?

Reeebuuk
  • 1,363
  • 2
  • 21
  • 42

1 Answers1

6

SprayJsonSupport works with spray-json (not with json4s). Thus you need to defined marshallers as follows

trait JsonMarshallers extends DefaultJsonProtocol {
  implicit val DigestItemWireFormat = jsonFormat6(DigestItemWire.apply)

  implicit val LocalDateTimeFormat = new JsonFormat[LocalDateTime] {

    private val iso_date_time = DateTimeFormatter.ISO_DATE_TIME

    def write(x: LocalDateTime) = JsString(iso_date_time.format(x))

    def read(value: JsValue) = value match {
      case JsString(x) => LocalDateTime.parse(x, iso_date_time)
      case x => throw new RuntimeException(s"Unexpected type %s on parsing of LocalDateTime type".format(x.getClass.getName))
    }
  }
}

and then import JsonMarshallers._ in the scope where you use them or mix it in with PriceServiceRoute and import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ at the beginning of the file.

expert
  • 29,290
  • 30
  • 110
  • 214
  • what kind of class is DigestItemWire? Don't have it in scope. – Reeebuuk Nov 06 '15 at 20:57
  • @Reeebuuk That's just example of case class that you want to serialize/deserialize like `CalculatePriceForRangeDto` in your case. – expert Nov 06 '15 at 21:47
  • tried that but I get Error: type mismatch; found : (Int, Long, Long) => com.example.crudapi.http.routes.CalculatePriceForRangeDto required: (?, ?, ?, ?, ?, ?) => ? Note: implicit value CalculatePriceForRangeDtoFormat is not applicable here because it comes after the application point and it lacks an explicit result type implicit val CalculatePriceForRangeDtoFormat = jsonFormat6(CalculatePriceForRangeDto.apply) – Reeebuuk Nov 06 '15 at 22:31
  • 1
    @Reeebuuk Try `jsonFormat3(CalculatePriceForRangeDto.apply)`. Number at the end of the name of method indicates number of fields in your case class. – expert Nov 06 '15 at 22:33
  • thx, learned something new already :) now that part compiles but the error is the same. I've just mixed in your trait in PriceServiceRoute. – Reeebuuk Nov 06 '15 at 22:42
  • 3
    Hmm, try adding `import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._` at the beginning of the file please. – expert Nov 06 '15 at 22:47
  • it worked now. I have one question only. How come that in this example http://www.typesafe.com/activator/template/akka-dddd-cqrs they didn't have to explicitly create formatter for every case class you serialize/deserialize? – Reeebuuk Nov 07 '15 at 09:04
  • 1
    @Reeebuuk I'm glad I helped. Please don't forget to accept the answer. json4s uses reflection (which is slow) thus it doesn't need excplicit serializer. – expert Nov 08 '15 at 21:51