Akka HTTPでJSONを使ってみる

Akka HTTPの入門についてはセプテーニさんのこちらの記事がわかりやすいです。

labs.septeni.co.jp

APIサーバにAkka HTTPを使ってみようかなぁと思っているので試しにリクエスト、レスポンスにJSONを使うのをやってみました。spray-jsonを使うモジュールが用意されているみたいなので依存関係に追加します。

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-http-experimental" % "2.4.6",
  "com.typesafe.akka" %% "akka-http-spray-json-experimental" % "2.4.6"
)

コードは以下のような感じ。ちょっと関係ない部分も入っちゃってますが、ケースクラスのプロパティ数に応じてjsonFormat1jsonFormat22を使ってimplicit valを定義しておけばいいみたい。

import akka.actor._
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._

object HelloApiServer extends App {

  // JSONをマッピングするケースクラス
  case class HelloRequest(name: String)
  case class HelloResponse(message: String)

  // JSON変換に必要なJsonFormatを定義
  implicit val helloRequestProtocol = jsonFormat1(HelloRequest)
  implicit val helloResponseProtocol = jsonFormat1(HelloResponse)

  implicit val actorSystem = ActorSystem("my-system")
  implicit val flowMaterializer = ActorMaterializer()

  val route = get {
    pathEndOrSingleSlash {
      handleWith((request: HttpRequest) => "API is ready.")
    }
  } ~ path("hello") {
    post {
      entity(as[HelloRequest]){ request =>
        complete {
          HelloResponse(message = s"Hello, ${request.name}!")
        }
      }
    }
  }

  val serverBinding = Http(actorSystem)
    .bindAndHandle(route, interface = "localhost", port = 8080)

}

バックエンドの処理ではJSON変換に主にJacksonを使っているのですが、Akka HTTPを使うならspray-jsonに統一したほうがいいかなぁ。