Что такое Ктор?

На первый взгляд Ktor (произносится как Kay-tor) кажется еще одним асинхронным фреймворком для веб-приложений, и так оно и есть. Если у вас есть опыт работы с такими фреймворками, как Express.js или Gin, вы наверняка почувствуете себя как дома с декларативным характером Ktor. Ktor разработан исключительно на Kotlin командой, стоящей за самим языком. Я также упоминал, что он отлично работает как HTTP-клиент? Но это тема для будущей публикации, а пока давайте остановимся на серверной стороне вещей.

Требования

Вы можете использовать вашу любимую IDE для работы. Мне нравится использовать IntelliJ Community Edition, потому что он отлично работает с Kotlin. Здесь нет необходимости в окончательной редакции, однако, если у вас есть лицензия, вы можете использовать плагин Ktor для некоторых дополнительных функций.

Что касается времени выполнения, я бы рекомендовал использовать GraalVM 11, он загружает все быстро и занимает мало памяти. Все с OpenJDK, так что проблем с лицензией здесь тоже нет.

Что ж, теперь, когда у вас все настроено и готово к работе, приступим.

Использование стартера Ktor

Самый простой способ создать проект с Ktor - перейти на https://start.ktor.io/#. Это генератор проектов для Ktor, в котором мы настроим большинство наших начальных функций.

Во-первых, давайте поговорим о настройках, доступных на самой левой панели.

Мы будем использовать Gradle в качестве инструмента сборки с Kotlin DSL, что делает его очень аккуратным и читаемым. Если вы предпочитаете использовать Gradle как есть или даже Maven, вы можете выбрать его с помощью первого поля.

Как вы увидите в этой серии статей, Ktor очень гибок, поэтому он позволяет нам выбирать, на каком серверном движке мы хотим запустить наш проект. До сих пор я успешно использовал Netty, он отлично работает на таких платформах, как Heroku, которые вы можете легко развернуть через их интерфейс командной строки. Не беспокойтесь об этом сейчас, мы расскажем об этом в одной из следующих публикаций.

Затем нам нужно определить, какие функции мы хотели бы установить в нашем проекте. Все они могут быть установлены позже, но в сегодняшней статье мы проверим все, что нам нужно, чтобы начать работу с правильным API.

На панели функций сервера следует выбрать:

  • Заголовки по умолчанию (из раздела «Функции»)

  • Маршрутизация (из «Функции»)

  • Согласование содержания (из раздела «Согласование содержания»)

Вот и все, что нам нужно установить, чтобы начать отвечать на HTTP-запросы. Теперь нажмите «Построить» в левом нижнем углу экрана и извлеките содержимое папки в любое удобное для вас место.

Откройте свой проект в IntelliJ и дождитесь, пока Gradle разрешит себя. Это может занять некоторое время, особенно если вы загружаете все артефакты впервые.

Начнем с экскурсии по нашему проекту. Сначала взгляните на папку «ресурсы». У нас есть файл с именем «application.conf», название говорит обо всем, но думайте об этом как о файле конфигурации вашей среды, вы должны использовать этот файл для хранения сторонних ключей API, настроек сервера и в основном все, что вы считаете необходимым. Вы также используете этот файл, чтобы указать, какие модули Ktor должен загружать при запуске.

Обратите внимание, что я добавил узел с именем «myCustomNode», это означает, что мы можем объявить все, что нам нужно внутри этого файла, и мы сможем получить его во время выполнения.

Теперь обратите внимание на модуль узла, загруженный в строке 11, затем перейдите к «src / Application.kt», обратите внимание, что загруженный модуль ссылается именно на этот файл, плюс «.module »в конце.

Почему .module? Вы можете спросить. Что ж, Ktor активно использует языковую функцию под названием Функции расширения, вы можете прочитать о ней здесь. Обратите внимание, что внутри Application.kt мы создали функцию .module для класса Application, поэтому поэтому нам нужно указать его внутри файла application.conf.

Прежде чем продолжить, давайте проверим, все ли работает нормально. Перейдите в меню Gradle, разверните меню «Задачи», затем «Приложение» и дважды щелкните «Выполнить».

Сервер должен запуститься, и ваш терминал будет выглядеть так.

Если у вас возникли проблемы с запуском приложения, не волнуйтесь, возможно, это просто некоторая неправильная конфигурация в вашем JDK, оставьте комментарий и дайте мне знать, чем я могу помочь.

В любом случае, перейдите по адресу http: // localhost: 8080 /, и вот он. Старый добрый ПРИВЕТ, МИР!

Остановите сервер, и давайте поговорим о составе «Application.kt». Во-первых, вы можете заметить пару аннотаций над модулем, который мы объявляем. Первый предназначен исключительно для того, чтобы IntelliJ не беспокоил нас по поводу того, что мы явно не используем функцию, которую мы объявляем. На момент написания IDE все еще не знает о связи между «application.conf» и «Application.kt», поэтому она предупредит нас об этом. Вы можете удалить его, если предупреждения о компиляции вас не пугают.

Во второй аннотации говорится, что во время компиляции компилятор должен генерировать перегрузки этого метода, потому что JVM не поддерживает необязательные параметры по умолчанию. Это потому, что наш параметр «тестирование» является необязательным. На данном этапе мы не будем рассматривать тестирование, поэтому давайте избавимся от него и немного очистим наш файл. Исходный «Application.kt» выглядел так.

После очистки это должно выглядеть так.

Я удалил аннотацию и необязательный параметр, обратите внимание, что я также удалил имя пакета файла, вы также должны отразить это изменение в своем файле «application.conf». Конечно, это вопрос предпочтений, так что сделайте это, если вам так нравится.

Если вы удалили имя пакета из файла «Application.kt», вам следует изменить загруженный модуль с «com.example.ApplicationKt.module» на просто «ApplicationKt.module».

Функции

Возможно, вы помните, что мы установили несколько функций при создании проекта, и именно здесь мы видим, как эти функции оживают. Каждая функция, которую вы добавляете в свой проект с помощью выбранного вами диспетчера зависимостей, должна быть установлена ​​при запуске. Это то, что мы делаем, когда пишем install () внутри нашего кода.

Этот метод получает объект типа ApplicationFeature ‹T› и интерфейс SAM (Что такое интерфейс SAM?) После того, как он дает нам возможность настроить эту функцию по мере необходимости.

Обратите внимание, что после того, как мы установили функцию «DefaultHeaders», мы могли бы также установить другие заголовки, потому что интерфейс предоставляет нам объект Configuration.

Это философия работы с каждой функцией, которую вы устанавливаете на Ktor. Давайте взглянем на функцию ContentNegotiation и приступим к написанию кода.

ContentNegotiation - это функция, которая позволяет нам сериализовать контент для наших клиентов, но, как я упоминал ранее, Ktor очень гибок и дает нам возможность использовать любой механизм сериализации, который нам нравится.

Мы будем использовать официальную библиотеку под названием «kotlinx.serialization» для сериализации наших данных в формате JSON. Для этого перейдите в файл «build.gradle». И примените изменения, указанные ниже.

Затем загрузите изменения Gradle.

Обратите внимание, что «json ()» теперь можно импортировать. Идите и импортируйте его.

Готово, мы готовы отправлять ответы в формате JSON нашим клиентам.

Не забудьте аннотировать классы, которые вы хотите сериализовать как JSON, с помощью аннотации @Serializable.

Маршрутизация

Возможно, вы заметили, что наша конечная точка hello world зарегистрирована прямо здесь, в нашем файле «Application.kt», это бесполезно, если у вашего API много конечных точек, поэтому я покажу вам, как группировать маршруты в отдельные файлы. Создайте пакет с именем «dog», файл Kotlin с именем «DogRoute» и еще один файл Kotlin с именем «Dog» (это должен быть классом данных), так должна выглядеть ваша структура.

Ваш файл «Dog.kt» должен выглядеть так.

И ваш файл «DogRoutes.kt» должен выглядеть так.

Затем перейдите в свой «Application.kt» и объявите «dogRoutes ()» вместо того, чтобы явно создавать маршруты, как это было раньше.

Теперь давайте создадим наш «DogService.kt», этот класс будет отвечать за предоставление данных, которые мы будем отображать с помощью нашего маршрутизатора. Подумайте о «DogRoutes.kt» как о вашем контроллере в архитектуре MVC. Конечно, вы сохраните «DogService.kt» внутри пакета «dog».

Давайте продолжим и применим эти методы в DogRoutes.kt.

Теперь давайте запустим наше приложение и все протестируем. Я буду использовать для этого Insomnia, но вы можете использовать все, что держит вашу лодку на плаву.

Как видите, все отлично работает! Прежде чем мы подведем итоги, в нашем приложении есть пара незакрепленных узлов, на которые я должен указать:

  • Нам нужно создавать «DogService» вручную каждый раз, когда он нам нужен. Это тема нашей следующей статьи: Внедрение зависимостей с использованием Koin.
  • Честно говоря, это бесполезно без уровня постоянства, поэтому мы также расскажем об этом в следующем посте, используя Ktorm.

Я надеюсь, что сегодня вы смогли сделать первые шаги с Ktor, если вам что-то понадобится, не стесняйтесь обращаться ко мне для получения дополнительной информации.

Я также должен указать на пару отличных учебных материалов, если вы хотите узнать больше о Kotlin или Ktor.

Вы можете найти весь исходный код здесь.

До следующего раза!