Маршруты и HttpRoutes
Функционально определяйте конечные точки.
«Маршруты и HttpRoutes» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Что такое http4s
http4s — полностью функциональная библиотека HTTP для Scala, построенная на cats-effect и потоках fs2. Запросы и ответы — неизменяемые значения, а эффекты представлены полиморфным типом эффекта F[_], например IO.
Вместо изменения сервлета вы описываете HTTP-сервис как функцию, преобразующую запрос в необязательный ответ с эффектом.
Тип HttpRoutes
Основная абстракция — HttpRoutes[F], псевдоним для Kleisli[OptionT[F, *], Request[F], Response[F]]. OptionT моделирует маршрут, который может не подойти и тогда не возвращает ответ.
Обычно эту сигнатуру не пишут вручную. Вместо этого маршруты создают конструктором HttpRoutes.of и частичной функцией.
import cats.effect.IO
import org.http4s._
import org.http4s.dsl.io._
val routes: HttpRoutes[IO] = HttpRoutes.of[IO] {
case GET -> Root / "hello" => Ok("hi")
}DSL http4s
Импорт DSL org.http4s.dsl.io._ добавляет сопоставители с образцом, такие как GET, Root и разделитель пути /, а также средства построения ответов, например Ok и NotFound.
Маршрут — это PartialFunction[Request[F], F[Response[F]]]. Несовпавшие случаи просто передаются дальше.
import org.http4s.dsl.io._
HttpRoutes.of[IO] {
case GET -> Root => Ok("root")
case GET -> Root / "ping" => Ok("pong")
}Сопоставление путей
Шаблоны путей читаются слева направо. Root — начальная косая черта, а каждый фрагмент / "segment" сопоставляется с одним буквальным сегментом пути.
Стрелка -> отделяет HTTP-метод от пути. Поэтому GET -> Root / "users" сопоставляется с GET /users.
HttpRoutes.of[IO] {
case GET -> Root / "users" => Ok("all users")
case GET -> Root / "users" / "me" => Ok("current user")
}Переменные пути
Связыватель в нижнем регистре без дополнительных обозначений захватывает сегмент пути как String. Здесь id связывается со всем, что находится после /users/.
Захваченные сегменты всегда являются строками; преобразуйте их в более содержательные типы самостоятельно или используйте показанные далее объекты-извлекатели.
HttpRoutes.of[IO] {
case GET -> Root / "users" / id =>
Ok(s"user $id")
}Типизированные извлекатели пути
http4s предоставляет извлекатели, такие как IntVar и LongVar, которые сопоставляются только с сегментами, преобразуемыми в соответствующий тип. Нечисловой сегмент передаёт управление следующему случаю.
Для предметных типов, например UUID, можно определить собственные извлекатели с помощью unapply.
HttpRoutes.of[IO] {
case GET -> Root / "users" / IntVar(id) =>
Ok(s"numeric user $id")
}Сопоставление методов
Извлекатель метода перед -> может быть любым из GET, POST, PUT, DELETE, PATCH и других. Один и тот же путь с разными методами образует отдельные случаи.
Если путь совпал, но метод нет, http4s автоматически возвращает 405 Method Not Allowed.
HttpRoutes.of[IO] {
case GET -> Root / "items" => Ok("list")
case POST -> Root / "items" => Created("made")
case DELETE -> Root / "items" / IntVar(i) => NoContent()
}Объединение маршрутов
Поскольку HttpRoutes[F] образует SemigroupK, несколько групп маршрутов можно объединить оператором <+>. Побеждает первая группа, создавшая ответ.
Это позволяет разделить маршруты по функциям на отдельные значения, а затем объединить их в одном месте.
import cats.syntax.semigroupk._
val all = userRoutes <+> itemRoutes <+> healthRoutesПреобразование маршрутов в HttpApp
Серверу нужна тотальная функция, а не частичная. HttpRoutes[F] преобразуется в HttpApp[F] с помощью .orNotFound, который возвращает 404, если ни один маршрут не подошёл.
HttpApp[F] — это Kleisli[F, Request[F], Response[F]], всегда возвращающий ответ.
import org.http4s.HttpApp
val app: HttpApp[IO] = routes.orNotFoundОбёртывание промежуточным слоем
Промежуточные слои — это функции HttpRoutes[F] => HttpRoutes[F] или функции над HttpApp. Они оборачивают сервис, добавляя журналирование, CORS, gzip или аутентификацию, не затрагивая логику маршрутов.
Встроенные примеры включают Logger, CORS и GZip из org.http4s.server.middleware.
import org.http4s.server.middleware.Logger
val logged = Logger.httpApp(logHeaders = true, logBody = false)(app)Параметры запроса в маршрутах
Параметры запроса сопоставляются объектами-сопоставителями, расширяющими QueryParamDecoderMatcher. В шаблоне пути они указываются после :?.
Для необязательных параметров используйте OptionalQueryParamDecoderMatcher; результатом будет Option.
object NameParam extends QueryParamDecoderMatcher[String]("name")
HttpRoutes.of[IO] {
case GET -> Root / "hi" :? NameParam(n) => Ok(s"hi $n")
}Быстрая проверка
Проверьте, насколько хорошо вы поняли объединение маршрутов.
Итоги
Вы создали маршруты с помощью HttpRoutes.of и DSL, сопоставляли методы и пути, захватывали переменные с помощью IntVar и сопоставителей, а также объединяли группы оператором <+>.
Маршруты являются частичными; .orNotFound превращает их в тотальный HttpApp, а промежуточные слои оборачивают сервисы, добавляя общую для разных компонентов логику.
Изучай Scala с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 39
- Уроки
- 143
Часто задаваемые вопросы
Урок «Маршруты и HttpRoutes» бесплатный?
Да — полный текст урока «Маршруты и HttpRoutes» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Маршруты и HttpRoutes»?
Функционально определяйте конечные точки. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Маршруты и HttpRoutes»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Маршруты и HttpRoutes
- Запросы и ответы
- Конечные точки JSON
- Предоставление приложения