http4sの紹介
1. 序章
http4sは、Scala 用の型付き機能的なHTTPライブラリであり、ストリーミングをサポートしています。 このチュートリアルでは、基本的なトピックに焦点を当てて、http4の概要を説明します。 特に、http4s DSLを使用して単純なHTTPサーバーを作成する方法と、http4sクライアントを使用してHTTP呼び出しを行う方法について説明します。
2. http4sの概要
http4sは、 cats (いくつかのコアデータ型を共有する)、 cats-effect (効果的なコードを記述するため)、などの他の多くのライブラリに基づいて構築されています。 ] FS2 (ストリーミングサポート用)。 build.sbtに依存関係を追加することから始めましょう:
val http4sVersion = "0.23.10"
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-dsl" % http4sVersion,
"org.http4s" %% "http4s-blaze-server" % http4sVersion,
"org.http4s" %% "http4s-blaze-client" % http4sVersion
)
3. http4sエンドポイント定義用のDSL
http4sは、リクエストとレスポンスの概念に基づいています。ライブラリは、サーバーを、リクエストをレスポンスに変換する関数を含むルートのセットとして定義します。タイプHttpRoutes[F]を使用します。 HttpRoutes [F] は、 Kleisli [OptionT [F、*]、Request、 Response] のエイリアスであり、かなり複雑なタイプです。 簡単に言うと、 Kleisli [OptionT [F、*]、Request、Response]はRequest => F [Option [Response]]のラッパーを表し、Fは効果的な操作を表します。を使用しますすべてのリクエストがレスポンスにつながるわけではないため、]オプション。 F が必要なのは、応答の生成にはデータベースへのアクセスや外部サービスの呼び出しなどの副作用が伴う可能性があるためです。 したがって、 HttpRoutes [F] は、RequestからオプションのResponseまでの関数を表し、副作用が含まれる可能性があります。 http4s DSLは、リクエストのパターンマッチングによってルートを定義するために使用されます。パラメータとして渡された文字列の長さを返す単純なエンドポイントを定義する方法を見てみましょう。
implicit val runtime: IORuntime = cats.effect.unsafe.IORuntime.global
val route: HttpRoutes[IO] = HttpRoutes.of[IO] {
case GET -> Root / "length" / str => Ok(str.length.toString)
}
上記の例では、エンドポイントの長さ/ {str}に応答する単一のルートを定義しています。ここで、{str}はパスパラメータを表します。 http4s DSLを使用して、最初にGETに応答することを指定します。 リクエスト、次にエンドポイント、そして動作。 Root は、サーバーによって構成されたルートパスを示します。 たとえば、 / をベースパスとして使用するようにサーバーを構成すると、エンドポイントは /lengthで応答します。 一方、サーバーがベースパスとして / api を使用している場合、 / api /lengthでエンドポイントに到達できます。 パスパラメータは、http4sではデフォルトでStringにマップされます。 したがって、strは自動的にStringを型として想定します。
4. サーバーの実行
ルートを定義した後、エンドポイントを公開して呼び出すことができるようにサーバーを設定できます。http4sは複数のサーバーバックグラウンドをサポートしています。 この例では、ネイティブサーバーであるblazeを使用します。 簡単なサーバーをセットアップしましょう:
object SimpleServer extends IOApp {
val route: HttpRoutes[IO] = HttpRoutes.of[IO] {
case GET -> Root / "length" / str => Ok(str.length.toString)
}
val app: Kleisli[IO, Request[IO], Response[IO]] = Router(
"/" -> route
).orNotFound
override def run(args: List[String]): IO[ExitCode] =
BlazeServerBuilder[IO]
.bindHttp(8080, "localhost")
.withHttpApp(app)
.resource
.useForever
.as(ExitCode.Success)
}
この場合、 app を作成するときに、ルートをベースエンドポイント「/」にバインドしました。 これにより、 /lengthエンドポイントへのルートが公開されます。 また、 .orNotFound を呼び出すことで、ユーザーから送信されたリクエストが定義したエンドポイントと一致しない場合は404応答が返される必要があるとも言います。
5. http4sHTTPクライアント
単純なHTTPサーバーを作成したら、それに対してHTTP呼び出しを行う方法を見てみましょう。
import cats.effect.unsafe.implicits.global
object SimpleClient extends IOApp {
def callEffect(client: Client[IO], str: String): IO[String] =
client.expect[String](uri"http://localhost:8080/length/" / str)
override def run(args: List[String]): IO[ExitCode] =
BlazeClientBuilder[IO].resource
.use { client =>
println(callEffect(client, "Baeldung").unsafeRunSync())
IO.unit
}
.as(ExitCode.Success)
}
以前と同様に、 IOApp を拡張し、blazeを背景として使用し、BlazeClientBuilderを作成します。 resource を取得した後、 use を呼び出します。これにより、実際のクライアントが割り当てられ、ラムダ関数に提供されます。
6. 結論
この記事では、非常に複雑なライブラリであるhttp4sの非常に簡単な紹介を見ました。 DSLを介したエンドポイントの定義と、HTTP呼び出しを記述および実行する方法を確認しました。 いつものように、コードはGitHubにあります。