Создайте простой API с базой данных PostgreSQL
С самого первого выпуска Java позиционировала себя как язык программирования напиши один раз, запусти везде. Идея заключалась в том, что программист мог разработать приложение на Java, скомпилировать его в байт-код и превратить в исполняемый файл, который может работать на любой платформе, независимо от операционной системы или платформы. Частично это удалось сделать с помощью среды выполнения, известной как виртуальная машина Java или JVM.
К чести Java, JVM была (и остается!) Невероятно точно настроенной средой выполнения, которая абстрагировалась от базового оборудования компьютера. Хотя Java как язык программирования существует и по сей день, его часто считают громоздким, утомительным и представителем устаревшего подхода к реализации решений.
За последние десять лет было разработано все больше и больше языков, которые работают на JVM, но по внешнему виду и ощущениям не похожи на Java. Один из таких языков - Котлин. Из-за JVM он не имеет реальных преимуществ в производительности по сравнению с обычной Java. Тем не менее, его сила заключается в том, что он отдает приоритет удобочитаемости в отличие от Java. Рассмотрим, например, печать подстроки в Java:
// Java
String input = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42";
String answer = input.substring(input.indexOf("?") + 1);
System.out.println(answer);
Сначала вы должны получить индекс символа, который вы хотите включить в подстроку, добавить единицу (поскольку строки имеют нулевой индекс) и вызвать System.out.println
для записи в стандартный вывод.
В Котлине это намного короче:
// Kotlin
val input = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42"
val answer = input.substringAfter("?")
println(answer)
Kotlin вызвал такой большой интерес, что Google даже рекомендует его вместо Java для разработки приложений для Android.
В этом посте мы кратко рассмотрим, как разработать приложение на Kotlin. Мы создадим простой API с базой данных PostgreSQL и развернем его в Heroku, чтобы увидеть его вживую.
Предпосылки
Прежде чем мы начнем, вам необходимо убедиться, что на вашем компьютере установлено следующее программное обеспечение:
- Аккаунт на Heroku. Это совершенно бесплатно и не требует какой-либо платежной информации.
- Интерфейс командной строки Heroku. Как только ваше приложение будет размещено на Heroku, это значительно упростит управление им.
- Вам потребуется установить Kotlin (›= 1.4).
- Вам также понадобится установленный Gradle (›= 7.0).
Вам также нужно будет немного познакомиться с Git и установить его на свой компьютер.
Мы собираемся использовать IDE IntelliJ для этого приложения Kotlin. В их документации содержатся некоторые рекомендации по созданию нового проекта. Убедитесь, что вы выбрали следующие параметры:
- Мы хотим создать приложение Kotlin, которое использует Gradle в качестве системы сборки.
- Задайте имя проекта
kotlin-api
- Установите версию JDK на 16. Если у вас не установлена эта версия, вы можете выбрать «Загрузить JDK…» в раскрывающемся списке, а затем выбрать Oracle Open JDK версии 16.
После того, как IDE все настроит, у вас должна получиться структура каталогов, которая выглядит примерно так:
kotlin-api
├── build.gradle.kts
└── src
├── main
│ ├── kotlin
Наши файлы Kotlin будут храниться в src/main/kotlin
, а наша логика сборки будет в build.gradle.kts
.
Начиная
Gradle - это инструмент сборки для множества языков. Он также действует как инструмент управления зависимостями, аналогичный Maven. У вас уже есть несколько строк в вашем build.gradle.kts
файле, которые IDE автоматически добавила, чтобы быть полезными. Вы можете удалить все это и вместо этого вставить следующие строки:
plugins { id("java") id("org.jetbrains.kotlin.jvm") version "1.5.10" id("org.springframework.boot") version "2.4.3" id("io.spring.dependency-management") version "1.0.11.RELEASE" } group "com.example" version "0.0.1" repositories { mavenCentral() } dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter") developmentOnly("org.springframework.boot:spring-boot-devtools") }
В этих строках указываются зависимости нашего проекта и их местонахождение. Например, мы хотим использовать [org.springframework.boot](https://plugins.gradle.org/plugin/org.springframework.boot)
в версии 2.4.3, поэтому он определен в блоке plugins
. Мы указываем репозитории, где можно найти пакеты - в mavenCentral()
- и какие открытые классы мы хотим использовать (implementation( "org.springframework.boot:spring-boot-starter-web")
).
Давайте создадим два небольших файла для проверки нашей настройки. Создайте файл с именем Application.kt
в папке src/main/kotlin
и вставьте следующее:
package com.example
import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication open class Application
fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) }
Это запускает приложение по умолчанию, использующее платформу Spring. Настоящая магия происходит в следующем файле Controller.kt
, который вы должны создать вместе с Application.kt
в src / main / kotlin:
Здесь мы определяем маршрут (@GetMapping("/{name}")
), где {name}
- динамическое значение. Поместив этот декоратор над методом Kotlin (fun get
или «функция с именем get»), мы можем сопоставить маршрут с любым желаемым поведением - в данном случае, возвращая приветствие с именем пути для GET
запроса.
Чтобы IDE знала, как запускать наше приложение, нам нужно создать конфигурацию запуска. В верхней части меню IDE нажмите кнопку Добавить конфигурацию…. Выберите Добавить новую конфигурацию запуска, затем выберите Gradle из списка.
В качестве имени проекта Gradle введите kotlin-api
. В поле "Задачи" введите bootRun
. bootRun
- это задача Gradle, предоставляемая фреймворком Spring, которая скомпилирует наш код и запустит сервер. Нажмите «ОК», и теперь у вас должна появиться зеленая кнопка «Воспроизвести» в строке меню IDE. Когда вы щелкнете по нему, IDE выполнит gradle bootRun
, чтобы построить это приложение Kotlin и запустить сервер. Когда это закончится, перейдите к http://localhost:8080/world
. Вы должны увидеть красивое приветствие.
Взаимодействие с базой данных
А теперь перейдем к (несколько) серьезным вещам. Предположим, мы хотим подключить к этому проекту базу данных. В мире Maven / Java нам нужно обновить XML-файл и добавить ссылку на JAR-файл. В Gradle мы можем обойтись простым добавлением нескольких строк в наш build.gradle.kts
файл:
dependencies { # ...
implementation("com.zaxxer:HikariCP:4.0.3") runtimeOnly("org.postgresql:postgresql")
# ... }
Здесь мы включили в наш проект HikariCP, популярный драйвер подключения к базе данных. Мы также указываем, что хотим загрузить org.postgresql
библиотеку во время выполнения. С помощью этих двух строк мы сообщаем нашей конфигурации, что хотим взаимодействовать с базой данных PostgreSQL. Если у вас уже есть база данных PostgreSQL, работающая локально, это прекрасно. Вы сможете продолжить оставшуюся часть этого руководства локально и увидеть результаты при просмотре localhost. Если у вас нет PostgreSQL, не волнуйтесь - мы покажем вам, насколько легко развернуть это приложение на Heroku, которое позаботится об инфраструктуре за вас.
Вернитесь к Controller.kt
и замените его содержимым ниже. Это берет кое-что из того, что у нас было раньше, но добавляет к этому. Вскоре мы рассмотрим изменения.
Здесь много всего происходит! Начнем снизу. Мы определяем функцию с именем dataSource
, которая обеспечивает соединение с нашей базой данных. Поскольку мы создаем 12-факторное приложение, учетные данные нашей базы данных хранятся в переменной среды с именем DATABASE_URL
. Мы получаем этот URL-адрес и вытаскиваем из него имя пользователя и пароль, если он существует. Если нет, мы проверяем еще две переменные среды на предмет этой информации - DATABASE_USERNAME
и DATABASE_PASSWORD
.
Затем мы объединяем всю эту информацию в формат, необходимый коннектору базы данных. Функция initDb
создает таблицу с именем names
с единственным текстовым столбцом с именем name
. Конечная точка /everyone
, как и раньше, имеет декоратор @GetMapping
. Это определяет GET /everyone
маршрут, который получает все имена из базы данных.
Наконец, мы добавили кое-что новенькое: декоратор @PostMapping
. Здесь нам нужно определить, какие типы контента может принимать этот POST
маршрут. В данном случае это consumes
тип носителя TEXT_PLAIN_VALUE
(другими словами, "Content-Type: text/plain"
). Какая бы строка информации мы ни поместили в тело запроса, она будет добавлена в базу данных. Всего за несколько строк мы создали небольшой API, который можно добавлять и запрашивать.
Если вы запустите этот сервер сейчас - и если у вас есть PostgreSQL, работающий локально, - вы сможете взаимодействовать с ним. Попробуйте сделать следующий запрос:
$ curl -H "Content-Type: text/plain" -X POST http://localhost:8080/add-name -d 'Frank'
Если вы перейдете к http://localhost:8080/everyone
, вы увидите, что Frank
был включен.
Развертывание на Heroku
Пришло время увидеть, насколько легко запустить Kotlin на Heroku. Во-первых, нам нужно создать файл, специфичный для Heroku: Procfile. Этот текстовый файл определяет, как наше приложение должно загружаться и работать.
Создайте файл с именем Procfile
в каталоге корневого уровня, рядом с вашим файлом build.gradle.kts
. Скопируйте и вставьте в него следующие строки:
web: java -jar build/libs/kotlin-api.jar --server.port=$PORT
Здесь мы говорим, что хотим, чтобы Heroku запускала java -jar build/libs/kotlin-api.jar
. Этот JAR упаковывается и создается в процессе развертывания; Heroku создаст его автоматически, потому что он знает, как выполнить задачу Gradle для этого. Мы также связываем переменную среды $PORT
, чтобы Heroku знал, какой порт слушает сервер.
Затем запустите следующие команды Git:
$ git init
$ git add .
$ git commit -m "Preparing my first Kotlin app"
Поскольку у нас установлен Heroku CLI, мы можем вызвать heroku create в командной строке для создания приложения:
$ heroku create
Creating app... done, ⬢ desolate-plains-67007
Created http://desolate-plains-67007.herokuapp.com/ | [email protected]:desolate-plains-67007.git
Вашему приложению будет присвоено случайное имя (в данном примере это desolate-plains-67007
), а также общедоступный URL.
Чтобы подготовить базу данных, мы используем команду heroku addons
. Вызов его без аргументов даст нам знать, если они существуют:
$ heroku addons
No add-ons for app desolate-plains-67007.
Для нашего приложения не существует надстроек, что имеет смысл - мы только что создали его! Чтобы добавить базу данных PostgreSQL, мы можем использовать команду addons:create
следующим образом:
$ heroku addons:create heroku-postgresql:hobby-dev
Heroku предлагает несколько уровней баз данных PostgreSQL. hobby-dev
- это уровень бесплатного пользования, поэтому мы можем поиграть с ним, не платя ни копейки.
Ваш код готов; ваше приложение Heroku настроено - вы готовы к развертыванию. Это легкая часть! Просто введите следующую команду:
$ git push heroku master
Ваш код будет отправлен на Heroku. С этого момента Heroku возьмет на себя управление. Вы увидите, как в терминале прокручиваются журналы сборки. Это покажет вам, что Heroku устанавливает от вашего имени и где вы находитесь в процессе сборки. После его завершения вы можете посетить свой специальный URL-адрес в браузере (в данном случае https://desolate-plains-67007.herokuapp.com
) и взаимодействовать с API в Интернете!
Узнать больше
Производительный дизайн и разборчивый синтаксис Kotlin в сочетании с простотой Gradle делают его идеальным для предприятий, которым необходимо полагаться на проверенные в боях пакеты Java. Благодаря своей совместимости с Java, Kotlin идеален в качестве переходного языка; обширные участки кода Java можно преобразовать в Kotlin, сохранив при этом работоспособное приложение. Развертывание в Heroku проходит гладко, и я даже не воспользовался преимуществами различных способов тонкой настройки приложений на основе Java и JVM для развертывания.