0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

アプリケーションを提供する

関数型Webサーバーを実行します。

「アプリケーションを提供する」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

Emberサーバー

http4sはバックエンド上でHttpApp[F]を実行します。現在の標準的な選択肢はEmberです。これはcats-effectとfs2を基盤とする純粋なScala製サーバーで、org.http4s.ember.server.EmberServerBuilderとして利用できます。

古いアプリケーションではBlazeを使っている場合もありますが、今後はEmberが推奨されます。

// build.sbt
// "org.http4s" %% "http4s-ember-server" % http4sV

サーバーの構築

EmberServerBuilder.default[F]は、流れるように設定できるビルダーを提供します。ホストとポートをバインドし、アプリを設定してから.buildを呼び出すと、Resource[F, Server]が得られます。

Resourceを使うと、シャットダウン時にソケットが確実に解放されます。

import com.comcast.ip4s._
import org.http4s.ember.server.EmberServerBuilder

EmberServerBuilder.default[IO]
  .withHost(ipv4"0.0.0.0")
  .withPort(port"8080")
  .withHttpApp(app)
  .build

ip4sリテラル

Emberは、型安全なネットワーキングのためにip4sの型を使用します。ipv4"..."とport"..."のインターポレーターはコンパイル時に検証するため、無効なアドレスや範囲外のポートはコンパイルできません。

これらを使うにはcom.comcast.ip4s._をインポートします。

import com.comcast.ip4s._

val host = host"localhost"
val p    = port"8080"

Resourceのライフサイクル

サーバーは、適切に開閉する必要があるソケットを所有するため、Resourceになっています。resource.use(_ => ...)を使うと、内側のエフェクトが実行されている間、サーバーを稼働させられます。

プロセスが割り込みを受けるまで実行するにはIO.neverを使います。

server.use(_ => IO.never).void

IOAppのエントリーポイント

http4sアプリのメインクラスはIOAppを継承します。IOAppは管理されたcats-effectランタイムを提供します。IO[ExitCode]を返すrunを実装してください。

IOAppがスレッドプール、シグナル処理、グレースフルシャットダウンを代わりに処理します。

import cats.effect.{IO, IOApp, ExitCode}

object Main extends IOApp {
  def run(args: List[String]): IO[ExitCode] = ???
}

完全なMain

すべてを組み合わせると、まずサーバーのリソースを構築し、次にIO.neverとともにuseしてプロセスを稼働させ続け、ExitCode.Successを返します。

これがhttp4sにおける標準的なエントリーポイントです。

def run(args: List[String]): IO[ExitCode] =
  EmberServerBuilder.default[IO]
    .withPort(port"8080")
    .withHttpApp(app)
    .build
    .use(_ => IO.never)
    .as(ExitCode.Success)

リソースの合成

実際のアプリケーションが取得するのはサーバーだけではありません。DBプール、HTTPクライアント、設定なども必要です。これらを単一のResourceに対するfor内包表記で合成すると、すべてが逆順に解放されます。

取得したクライアントをルートの構築に渡します。

for {
  client <- EmberClientBuilder.default[IO].build
  app     = buildApp(client)
  srv    <- serverResource(app)
} yield srv

グレースフルシャットダウン

サーバーはResource内にあるため、ファイバーをキャンセルすると(IOApp上でのSIGTERMなど)、ファイナライザーが実行され、新しい接続の受け付けを停止してソケットを閉じます。

Emberは設定可能なシャットダウンタイムアウトの間、処理中のリクエストが完了するのを待ちます。

EmberServerBuilder.default[IO]
  .withShutdownTimeout(30.seconds)
  .withHttpApp(app)
  .build

サーバーミドルウェア

最終的なHttpAppをサーバーミドルウェアでラップしてから、ビルダーに渡します。一般的なものにはLogger、CORS、GZip、ErrorHandlingがあります。

順序が重要です。最も外側のラッパーが最初にリクエストを受け取り、最後にレスポンスを確認します。

import org.http4s.server.middleware._

val finalApp = Logger.httpApp(true, false)(
  CORS.policy.withAllowOriginAll(app)
)

設定

cirisやpureconfigなどの設定ライブラリを使って、ホスト、ポート、シークレットを環境から読み込み、設定をResourceまたはエフェクトの一部として返します。

ポートをハードコードするのは避け、同じバイナリを複数の環境で実行できるようにします。

val port = sys.env.get("PORT")
  .flatMap(Port.fromString)
  .getOrElse(port"8080")

ヘルスチェックと可観測性

GET /healthのような生存確認用ルートを公開し、プロセスをオーケストレーターが検査できるように200を返します。可視性を高めるため、リクエストロギングとメトリクスのミドルウェアも追加します。

ヘルスチェックは低コストで依存関係を持たないものにし、下流サービスではなくプロセス自体の状態を反映させます。

val health = HttpRoutes.of[IO] {
  case GET -> Root / "health" => Ok("UP")
}

クイックチェック

サーバーがResourceとしてモデル化されている理由を思い出してください。

まとめ

EmberServerBuilderでアプリを提供し、ip4sリテラルでバインドして、build.use(_ => IO.never)を使いIOAppから実行しました。

リソースを合成し、ミドルウェアでラップし、環境から設定を読み込み、ヘルスチェック用ルートを追加しました。また、グレースフルシャットダウンにはResourceを利用しました。

よくある質問

「アプリケーションを提供する」レッスンは無料ですか?

はい。「アプリケーションを提供する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

「アプリケーションを提供する」で何を学びますか?

関数型Webサーバーを実行します。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「アプリケーションを提供する」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. RoutesとHttpRoutes
  2. リクエストとレスポンス
  3. JSONエンドポイント
  4. アプリケーションを提供する
← Scala for Backend Engineering & Functional Programmingに戻る