Your Location is: Home > Scala

Akka http: how to make complete function see my Encoders?

From: Peru View: 4663 Dmitry Reutov 


I have a couple of case classes and made encoders for them

trait appJSONProtocol extends DefaultJsonProtocol {
  implicit val jsCat = jsonFormat4(Category)
  implicit val jsCatRel = jsonFormat3(CategoryRel)

  implicit val encodeCat: Encoder[Category] =
    Encoder.forProduct4("id", "name", "parentId", "level")(u =>
      (,, u.parentId, u.level)

  implicit val encodeCatRel: Encoder[CategoryRel] =
    Encoder.forProduct6("id", "name", "parentId", "level", "parentOfMine", "children")(u =>
      (,, u.category.parentId, u.category.level, u.parent, u.children)

now i want to make response according these encoders

def completeTask[T] (task: Future[T])(
    implicit encoder: Encoder[T],
    m: ToEntityMarshaller[T]
  ) = {
    onComplete(task) {
      case Success(data) => {
        complete(OK, data)
      case Failure(throwable) =>
        complete(BadRequest, throwable.getMessage)

data.asJson works perfectly well, but complete function returns json as it does not see my encoders. It seems like it expects some EntityMarshaller parameter, but how and where can i apply Encoder then?

Best answer

Finally this implicit function helped to translate my encoders to ToEntityMarshaller type

implicit final def marshaller[A: Encoder]: ToEntityMarshaller[A] = {
    Marshaller.withFixedContentType(`application/json`) { a =>
      HttpEntity(`application/json`, a.asJson.noSpaces)

Another answer

While your solution works, there's not really a reason to write this yourself. There's an implementation in a library:

Mix in the akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport trait and you're done.