Scala for Backend Engineering & Functional Programming · Урок

Маршруты и HttpRoutes

Функционально определяйте конечные точки.

Урок 1 из 413 шагов

«Маршруты и 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 — локальная установка не требуется.

Все уроки этого курса

  1. Маршруты и HttpRoutes
  2. Запросы и ответы
  3. Конечные точки JSON
  4. Предоставление приложения
← Назад к Scala for Backend Engineering & Functional Programming