LoginSignup
2
1

More than 3 years have passed since last update.

Akka Httpを試してみる

Posted at

前置き

ScalaのWebフレームワークを触ってみる第2弾として、今回はAkka Http を軽〜く触ってみます。
Akka Http は正確にはフレームワークではなく、 HTTPベースのサービスを提供および利用するためのより一般的なツールキット との事。

The Akka HTTP modules implement a full server- and client-side HTTP stack on top of akka-actor and akka-stream. It’s not a web-framework but rather a more general toolkit for providing and consuming HTTP-based services. While interaction with a browser is of course also in scope it is not the primary focus of Akka HTTP.

事前準備

Akka Httpを動かすのに必要な次のものを事前にインストールしてください。今回は次の通り。

  • Java 11
  • Scala 2.13.3
  • sbt 1.3.13

Akka Httpプロジェクト作成

好きなところにディレクトリを作成して次のコマンドを実行
sbt new akka/akka-http-quickstart-scala.g8
対話形式で色々聞かれるので今回は次の構成とします。

name [My Akka HTTP Project]: akka-http-sample
scala_version [2.13.3]:
akka_http_version [10.2.0]:
akka_version [2.6.9]:
organization [com.example]:
package [com.example]:

作成されたプロジェクトをIntelliJで読み込むと次のように色々ファイル群が生成されています。
スクリーンショット 2020-09-26 14.20.30.png

JsonFormats
JSONのリクエスト/レスポンスをフォーマットして任意のcase classにマッピングしてくれる。QuickStartの例だと、UserUsersについて定義されている。
jsonFormatN()のNは対象case classの引数の数

QuickstartApp
サーバーの起動に関するメイン処理。ここでActorの起動や、Routeの指定をしている。

UserRegistry
Routeで処理している各種Userに関するCRUD処理を定義している。

UserRoutes
Routing定義

動作確認

実際に動かして確認してみます。

起動する

IntelliJで QuickstartAppのmainを実行するとサーバが http://localhost:8080 で起動します。

リクエストを投げてみる

UserRoutesには、既にユーザーに対する処理が実装されています。それぞれに対応するリクエストを投げてみます。

0. いきなり番外編

http://localhost:8080 に対する処理は実装されていませんので、対応するルーティングをちょっと記述します。

UserRoutes
val userRoutes: Route =
    pathSingleSlash { // 追加ここから
      get {
        complete((StatusCodes.NotFound, "hello"))
      }
    } ~ // 追加ここまで
    pathPrefix("users") { // 以下省略 }

これで http://localhost:8080 にアクセスすると "hello"が表示されます。

1. POST /users

この部分
post {
  entity(as[User]) { user =>
    complete(createUser(user))
    onSuccess(createUser(user)) { performed =>
      complete((StatusCodes.Created, performed))
    }
  }
}

リクエスト

POST http://localhost:8080/users
Content-Type: application/json

{
  "name": "山田太郎",
  "age": 18,
  "countryOfResidence": "Japan"
}

JsonFormatsの次の定義を解釈してJSONをUserケースクラスにマッピングしてくれます。

implicit val userJsonFormat = jsonFormat3(User)

レスポンス

{
  "description": "User 山田太郎 created."
}

Response code: 201 (Created); Time: 21ms; Content length: 36 byte

2. GET /users

この部分
get {
  complete(getUsers())
}

リクエスト

GET http://localhost:8080/users
Accept: application/json

レスポンス

{
  "users": [
    {
      "age": 18,
      "countryOfResidence": "Japan",
      "name": "山田太郎"
    },
    {
      "age": 22,
      "countryOfResidence": "Japan",
      "name": "田中次郎"
    }
  ]
}

Response code: 200 (OK); Time: 694ms; Content length: 119 bytes

こちらも、JsonFormatsの次の定義を解釈してUsersケースクラスをJSONにパースしてくれます。

implicit val usersJsonFormat = jsonFormat1(Users)

3. GET /users/{name}

この部分
path(Segment) { name =>  //path(Segment)でリクエスト中の{name}の文字列を取得している
  concat(
    get {
      //#retrieve-user-info
      rejectEmptyResponse {
        onSuccess(getUser(name)) { response =>
          complete(response.maybeUser)
        }
      }
    //#retrieve-user-info
    },

リクエスト

GET http://localhost:8080/users/山田太郎
Accept: application/json

レスポンス

{
  "age": 18,
  "countryOfResidence": "Japan",
  "name": "山田太郎"
}

Response code: 200 (OK); Time: 23ms; Content length: 53 bytes

4. DELETE /users/{name}

この部分
path(Segment) { name => 
  concat(
    { // 省略・・・
    },
    delete {
      //#users-delete-logic
      onSuccess(deleteUser(name)) { performed =>
        complete((StatusCodes.OK, performed))
       }
      //#users-delete-logic
    }
  )
}

リクエスト

DELETE http://localhost:8080/users/山田太郎

レスポンス

{
  "description": "User 山田太郎 deleted."
}

Response code: 200 (OK); Time: 689ms; Content length: 36 bytes

まとめ

ほんとに軽〜く触ってみましたが、Quickstartで生成されるサンプルにAkkaやActorの処理が入り込んでいるので、パッと見はとっつきづらい印象がありますね。軽いREST APIを書くのであれば Scalatraの方が個人的にはわかり易かったです。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1