0

I am using akka http. In my API layer I have defined the following classes:

sealed abstract class ApiResponse[A](val content: A, val code: Int)

final case class Success[A](override val content: A, override val code: Int) extends ApiResponse(content, code)

final case class Failure[A](override val content: A, override val code: Int) extends ApiResponse(content, code)

I would like to have them marshalled into following jsons respectively:

{ "ok" : "true", "content" : "..." }

{ "ok" : "false", "content" : "..." }

And also I would like to have the code to be set as http status code in the response. I tried to define ToReponseMarshaller for this but got stuck, not sure if this is the correct choice for my problem.

user3763116
  • 235
  • 1
  • 2
  • 11

1 Answers1

1

I would recommend using spray-json for this and the Akka-http integration for it. You should define your case classes the same way you want your json objects:

case Response(ok: String, content: String)

Then you need to create a a JsonProtocol:

trait ResponseJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val responseFormat = jsonFormat2(Response)
}

And the use it in your routes:

val route = 
  path("something") {
    complete(Response("false", "some content"))
  }

If you want to respond with different status code you can pass tuple to complete like this

complete {
  StatusCodes.BandwidthLimitExceeded -> MyCustomObject("blah blah")
}

Required imports for this are:

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._

Also, you will need to bring a new dependency:

libraryDependencies += "com.typesafe.akka" % "akka-http-spray-json-experimental_2.11" % "2.4.11"
expert
  • 29,290
  • 30
  • 110
  • 214
hveiga
  • 6,725
  • 7
  • 54
  • 78
  • How can I set different status codes using your solution? – user3763116 Oct 27 '16 at 14:52
  • you just need to have a `Response` instance with the values you need. You can do `Response("false", "some content")` or `Response("true", "some other content")` and you will be `{ "ok" : "false", "content" : "some content" }` or `{ "ok" : "true", "content" : "some other content" }` – hveiga Oct 27 '16 at 14:56
  • If I will use your solution I will need to repeat the code which I want to use for a particular failure in every route. Another thing is that content in the Response class is defined as String which greatly simplifies things and which does not work for me. – user3763116 Oct 27 '16 at 15:24