ScalaのAkkaのHTTPモジュールAkka-HTTPをさわってみる

What Akka-HTTP

Scala Documentation · Contents
Akka-HTTPは、Akka-ActorベースのHTTPの機能を提供するモジュール。
Sprayと似ており、柔軟なルーティングを提供する。



準備

tabakazu.hatenablog.com
この記事で詳しく書いてますが、面倒な方はコピペで。

mkdir akkahttp_app
cd akkahttp_app
mkdir p- src/scala/main/
touch build.sbt
touch src/scala/main/Boot.scala



Using Akka-HTTP

Introduction · Contents
experimentalがあるので便利!

// build.sbt

name := "akkahttp_app"
 
version := "1.0"
 
scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
    "com.typesafe.akka" %% "akka-http-core" % "2.4.11",
    "com.typesafe.akka" %% "akka-http-experimental" % "2.4.11",
    "com.typesafe.akka" %% "akka-http-xml-experimental" % "2.4.11"
)



HTTP Server

// src/scala/main/Boot.scala

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import scala.io.StdIn

object Boot {
  def main(args: Array[String]) {

    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher

    val route =
      path("hello") {
        get {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
        }
      }

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)

    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine()
    bindingFuture
      .flatMap(_.unbind())
      .onComplete(_ => system.terminate())
  }
}
# コンパイルと実行
sbt compile run
確認

http://localhost:8080/hello Say hello to akka-http と表示されます。



Basic認証

authenticateBasic · Contents
Basic認証機能も簡単に付けれます。
UserPassなやつです。

// src/scala/main/Boot.scala

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.directives.Credentials
import akka.stream.ActorMaterializer
import scala.io.StdIn

object Boot {
  def main(args: Array[String]) {

    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher

    def myUserPassAuthenticator(credentials: Credentials): Option[String] =
      credentials match {
        case p @ Credentials.Provided(id)
          if id.equals("bob") && p.verify("123") => Some(id)
        case _ => None
      }

    val route =
      Route.seal {
        path("hello") {
          authenticateBasic(realm = "secure site", myUserPassAuthenticator) { userName =>
            get {
              complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>Say hello to $userName</h1>"))
            }
          }
        }
      }

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)

    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine()
    bindingFuture
      .flatMap(_.unbind())
      .onComplete(_ => system.terminate())
  }
}
# コンパイルと実行
sbt compile run
確認

http://localhost:8080/hello
ユーザ「bob」、パスワードは「123」です。
結果は、Say hello to bob(ユーザ名)が表示されます。