2020年7月12日 星期日

Scala 的 HTTP 伺服器:http4s

在 Ubuntu 準備 sbt 環境

雖然覺得這個步驟蠻沒意義的,不過總之我又久違地在 Windows 上開了個 Ubuntu 20.04 的 container。

在安裝 sbt 之前,需要先加入 sbt 的 repository 到 apt 的來源。

echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
sudo apt-get update

接著就是安裝 Java 與 sbt。

sudo apt-get install -y default-jre sbt

以我目前這個時間點來說,會裝出來的版本如下:

Java: 11.0.7
sbt: 1.3.13
產生 http4s 範例專案

執行以下的初始化指令,讓 sbt 產生一個 http4s 的範例小專案。

sbt new http4s/http4s.g8 -b 0.21

這個指令其實本來在 http4s 的 Quick Start 裡是還有指定 sbt 版本的 -sbt-version 1.3.12,不過這裡就把它拿掉,讓它直接用剛裝的版本了。產生過程會問一些問題,這裡基本上我全都用預設值了。

接著就可以來看看產生出來的檔案有哪些內容了:

build.sbt

organization := "com.example"
name := "scala-test"
version := "0.0.1-SNAPSHOT"
scalaVersion := "2.12.4"

val Http4sVersion = "0.16.6a"
val Specs2Version = "4.0.2"
val LogbackVersion = "1.2.3"

libraryDependencies ++= Seq(
  "org.http4s"     %% "http4s-blaze-server"  % Http4sVersion,
  "org.http4s"     %% "http4s-circe"         % Http4sVersion,
  "org.http4s"     %% "http4s-dsl"           % Http4sVersion,
  "org.specs2"     %% "specs2-core"          % Specs2Version % "test",
  "ch.qos.logback" %  "logback-classic"      % LogbackVersion
)

HelloWorld.scala

package com.example.scalatest

import io.circe._
import org.http4s._
import org.http4s.circe._
import org.http4s.server._
import org.http4s.dsl._

object HelloWorld {
  val service = HttpService {
    case GET -> Root / "hello" / name =>
      Ok(Json.obj("message" -> Json.fromString(s"Hello, ${name}")))
  }
}

Server.scala

package com.example.scalatest

import scala.util.Properties.envOrNone
import org.http4s.server.blaze.BlazeBuilder
import org.http4s.util.ProcessApp
import scalaz.concurrent.Task
import scalaz.stream.Process

object Server extends ProcessApp {
  val port: Int = envOrNone("HTTP_PORT").fold(8080)(_.toInt)

  def process(args: List[String]): Process[Task, Nothing] = BlazeBuilder.bindHttp(port)
    .mountService(HelloWorld.service, "/")
    .serve
}

這樣就是個最簡單能跑的 Scala + http4s 的小專案了,可以透過 sbt run 啟動伺服器。執行後可以看到像是這樣的啟動訊息:

[info] Loading settings from plugins.sbt ...
[info] Loading project definition from G:\java\intellij\scala-http4s-test\project
[info] Loading settings from build.sbt ...
[info] Set current project to scala-test (in build file:/G:/java/intellij/scala-http4s-test/)
[info] Running com.example.scalatest.Server
[pool-6-thread-4] INFO  o.h.b.c.n.NIO1SocketServerGroup - Service bound to address /127.0.0.1:8080
[pool-6-thread-4] INFO  o.h.s.b.BlazeBuilder - http4s v0.16.6a on blaze v0.12.11 started at http://127.0.0.1:8080/

啟動完成後,就可以用瀏覽器連上 http://127.0.0.1:8080/ 了,例如範例的 REST API 網址會是 http://127.0.0.1:8080/hello/michael,因為輸入的 {name} 是 michael,所以就會獲得 {"message":"Hello, michael"} 的 JSON 回覆。

參考資料
  1. Installing sbt on Linux

沒有留言: