今回は前章からの続きでzio-http
のMiddlewareについて見ていきます。
zio-http
のMiddleware
今回は既存のApplicationServiceImpl.scala
のgetCookie
関数、postApi
関数の末尾に付与されている文字化け対策のためのヘッダ付与処理を共通化し、個々の関数毎にこのようなヘッダ付与処理を加える必要がなくなるようにMiddlewareを利用していきます。
Middlewareは上記のように複数のパスについて共通するような処理を共通化するなどといった目的のために使います。
今回のような単純なレスポンスヘッダの付与以外にもベーシック認証、ロギング、様々な認証処理のために利用できます。
具体的な利用例
Middlewareの使い方について詳しく見ていきます。
まず以下の様にコードを修正します。
case class ApplicationServiceImpl(client: Client) extends ApplicationService {
(中略)
override def getCookie(request: Request): ZIO[Any, Throwable, Response] = for {
(中略)
} yield Response.text(cookie)
(中略)
override def postApi(param:String): ZIO[Any, Throwable, Response] = for{
(中略)
} yield Response.text(s"http://localhost:8080/postTest:$data")
}
getCookie
関数、postApi
関数の末尾から.setHeaders(Headers("Content-Type", "text/plain;charset=UTF-8")) // 文字化け対策をしています
を削除しています。
MainApp
について以下のように修正します。
object MainApp extends ZIOAppDefault {
override val run: ZIO[Any, Throwable, Nothing] =
Server
.serve((TestController() @@ HttpAppMiddleware.addHeader("Content-Type", "text/html;charset=UTF-8")).catchAllCauseZIO { _ =>
// エラー処理
ZIO.succeed(Response(status = Status.InternalServerError))
})
.provide(
Server.default,
ApplicationServiceImpl.layer,
Client.default
)
}
修正後、実行し、例えばhttp://localhost:8080/postApi/test
にアクセスすると以下の出力が文字化けすることなく得られます。
http://localhost:8080/postTest:あなたの名前はtestです。
また、レスポンスヘッダに対してもContent-Type:text/html;charset=UTF-8
が設定されていることが確認できるかと思います。
さらに例えばhttp://localhost:8080/text
Middleware利用部分
今回削除した.setHeaders(Headers("Content-Type", "text/plain;charset=UTF-8"))
という処理を別の場所で代わりに行うためにMainApp
を修正しています。
以下の部分になります。
TestController() @@ HttpAppMiddleware.addHeader("Content-Type", "text/html;charset=UTF-8")
レスポンスヘッダを付加するMiddlewareはHttpAppMiddleware.addHeader
になりますので、それを使っています。
そして、そのMiddlewareを@@
関数でコントローラに対して登録しています。
終わりに
今回はレスポンスヘッダをMiddlewareを使い付与する例を見てきました。
その他にもベーシック認証については以下の様に追加することができますので、ご確認頂ければと思います。
次回は単体テストについて見ていきます。
前章:外部Web APIアクセス
次章:単体テスト
演習
- 今回のレスポンスヘッダ付与の例について実際に動かし、挙動を確かめてください。
- 解答例は以下になります。
https://github.com/hatuda/zio-practice/tree/CHAPTER8
- 解答例は以下になります。