Предоставление приложения
Запустите функциональный веб-сервер.
«Предоставление приложения» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Сервер Ember
http4s запускает ваше приложение HttpApp[F] на серверной платформе. Современный вариант по умолчанию — Ember, чистый сервер на Scala, построенный на cats-effect и fs2 и доступный как 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, который предоставляет управляемую среду выполнения cats-effect. Вам нужно реализовать run, возвращающий IO[ExitCode].
IOApp самостоятельно обрабатывает пулы потоков, сигналы и корректное завершение работы.
import cats.effect.{IO, IOApp, ExitCode}
object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] = ???
}Полный главный модуль
Соберите всё вместе: создайте ресурс сервера, затем используйте его с IO.never, чтобы процесс продолжал работать, и верните 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)Композиция ресурсов
Реальные приложения получают не только сервер: им также нужны пул базы данных, HTTP-клиент и конфигурация. Объедините их в одной конструкции for над Resource, чтобы все ресурсы освобождались в обратном порядке.
Передайте полученные клиенты при создании маршрутов.
for {
client <- EmberClientBuilder.default[IO].build
app = buildApp(client)
srv <- serverResource(app)
} yield srvКорректное завершение работы
Поскольку сервер находится в Resource, отмена волокна, например при SIGTERM под управлением IOApp, запускает финализатор, который прекращает принимать соединения и закрывает сокет.
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 и запустили его из IOApp с помощью build.use(_ => IO.never).
Вы объединили ресурсы, обернули приложение промежуточным ПО, прочитали конфигурацию из окружения, добавили маршрут проверки работоспособности и использовали Resource для корректного завершения работы.
Часто задаваемые вопросы
Урок «Предоставление приложения» бесплатный?
Да — полный текст урока «Предоставление приложения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Предоставление приложения»?
Запустите функциональный веб-сервер. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Предоставление приложения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Маршруты и HttpRoutes
- Запросы и ответы
- Конечные точки JSON
- Предоставление приложения