Использование Kotlin для серверной разработки: краткий обзор

Опубликовано: 2022-03-11

Мне не нужно представлять Kotlin нативным разработчикам Android, поскольку в мае 2017 года Google объявил, что он станет официальным языком разработки для Android. С тех пор он приобрел большую популярность как основной язык для разработки новых и блестящих приложений для Android. Он решает многие болевые точки Java, поэтому новые приложения в основном пишутся на нем, а старые переписываются на нем.

Нет сомнений в том, что он отлично подходит для фронтенда приложений, и когда вы впервые упоминаете Kotlin, у большинства людей он ассоциируется с ОС Android. Однако в этой статье я расскажу о Kotlin как о внутреннем языке и хочу поделиться своей историей о создании быстрого, надежного и асинхронного серверного кода Kotlin для моего хобби-проекта на Android. Я не буду обсуждать, о чем проект, так как это выходит за рамки этой статьи; скорее я сосредоточусь на объяснении, почему я выбрал Kotlin и почему я считаю его отличным языком для написания серверных приложений или REST API.

Почему Котлин?

Позвольте мне вернуться к самому началу моего пути. У меня всегда были предпринимательские амбиции, и я думал, что первый шаг на этом пути — создать что-то самостоятельно. Ничего грандиозного, ничего изменяющего мир, просто что-то маленькое, что может быть полезно мне и, возможно, моей семье и друзьям. После того, как у меня появилась разумная идея, я сразу же взялся за нее и начал ее реализовывать. Первое, что вы делаете в начале любого проекта, — это выбираете инструменты. В конце концов, правильный набор инструментов может сэкономить вам много времени и денег в долгосрочной перспективе. Вот что я сделал.

Я в первую очередь Java-разработчик. Я написал несколько серверных систем и REST API, используя Java и Spring, и я действительно думаю, что эти два инструмента — отличные инструменты для таких вещей. Java сама по себе является всеобъемлющим языком, но в сочетании со Spring нет ничего невозможного.

Однако в супе есть только один крошечный волосок. Многословие. Хотя Spring и последние версии Java очень помогают в этом, вам все равно приходится обрабатывать много стандартного кода. И как однажды сказал мне один отличный парень, самый безопасный, самый надежный и безглючный код — это тот код, который не записан. Возьмем, к примеру, этот тривиальный класс Java:

 public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }

На мой взгляд, это слишком много кода, чтобы просто сказать: «Мне нужен класс с двумя полями только для чтения». Хуже всего то, что конструктор и методы были сгенерированы автоматически. Тем не менее, когда вы просматриваете запрос на вытягивание, вы всегда просматриваете их, потому что вы никогда не знаете, нужны они вам или нет. Конечно, это можно сократить с помощью сторонних библиотек, таких как Lombok, но было бы неплохо, если бы мы могли сделать это из коробки? Давайте посмотрим на этот же класс в Котлине:

 class Person( val name: String, val age: Int )

Это определенно короче и проще. Переменные являются окончательными, поскольку мы используем ключевое слово val ; конструктор и геттеры генерируются во время компиляции. Если мы предпочитаем не иметь неизменного объекта-человека, мы можем просто изменить val на var , и вуаля, у нас есть изменяемый человек, и все, что нам нужно сделать, это просто изменить одну букву.

Моя вторая любимая часть в простом классе Java POJO — переопределенные equals() и hashCode() . В большинстве случаев они снова генерируются автоматически, но вам всегда нужно просматривать их, просто чтобы убедиться. Хорошая новость заключается в том, что Kotlin может справиться и с этим. Просто измените свой class на data class , и вы получите equals() и hashCode() из коробки.

 data class Person( val name: String, val age: Int )

Короче говоря, хоть я и люблю Java, мне хотелось как можно быстрее за короткое время создать минимально жизнеспособный продукт для своего проекта. А в случае разработки программного обеспечения самый простой способ добиться этого — писать меньше кода. Таким образом, мой поиск лучшего языка для внутренней разработки продолжился. Помня об этом, я сначала переключился на Node.js. У него есть несколько существенных преимуществ: несколько строк, и ваш сервер Express запущен и работает, слушает порт 8080 и отвечает Hello World! каждый раз, когда вы отправляете запрос на получение.

 let express = require('express') let app = express(); app.get('/', (req, res) => res.send('Hello World!')); app.listen(8080);

Легко, просто и быстро. Именно то, что вы ожидаете от одного из самых популярных языков программирования. Мне нравится работать с JavaScript, и на мгновение я подумал, что нашел правильный инструмент, но затем меня преследовал тот факт, что JavaScript динамически типизирован. Не поймите меня неправильно, я действительно думаю, что динамическая типизация хороша во внешнем интерфейсе, но по моему опыту наличие статической типизированной серверной части просто дает вам дополнительную уверенность в том, что ваш сервер с меньшей вероятностью выйдет из строя во время выполнения из-за несоответствия типов. . И давайте будем честными, когда ваш сервер обслуживает несколько сотен тысяч пользователей, вы действительно не хотите, чтобы это произошло. Однако Node.js предлагал одну замечательную функцию, которую я хотел сохранить, а именно возможность легко писать асинхронный код и сервисы.

Имея в виду эти требования, я решил написать свою серверную часть Kotlin Android также на Kotlin.

Котлин: краткий обзор

Для тех из вас, кто никогда о нем раньше не слышал, Kotlin — это статически типизированный язык программирования с открытым исходным кодом, который поддерживает как объектно-ориентированное, так и функциональное программирование. Он предоставляет такой же синтаксис и концепции, что и C#, Java или Scala, и в основном предназначен для JVM, но также имеет варианты, предназначенные для JavaScript или машинного кода. Он очень похож на Java в том смысле, что Kotlin/JVM компилируется в байт-код Java, поэтому для тех внутренних инженеров, которые имеют опыт работы с JVM, Kotlin будет легко понять.

Как говорится на его официальной странице, цель Kotlin не в том, чтобы быть уникальным, а в том, чтобы черпать вдохновение и лучшие практики из десятилетий разработки языка. Его можно использовать с любой Java IDE или из командной строки, но лично я предпочитаю и рекомендую использовать его с IntelliJ. Он активно поддерживается и обновляется командой JetBrains, и не беспокойтесь о покупке платной версии — если вы только начали работать с Kotlin, общедоступная версия IntelliJ удовлетворит все ваши потребности. Три наиболее важных аспекта Kotlin, на которые я хотел бы обратить внимание, это то, что он: а) лаконичен (значительно сокращает шаблонный код), б) безопасен (во-первых, он создан для того, чтобы избежать исключений нулевого указателя) и в) ) совместимость (вы можете использовать существующие библиотеки для JVM, Android или браузера).

Котлин Корутины

Все хотят иметь сервисы, которые быстро обслуживают пользователей. Чтобы достичь максимальной производительности вашего сервера, первое, что вы можете сделать, это создать многопоточное приложение. Java довольно громоздка с этим. Когда вы изучаете Java, вы сначала узнаете, что если вам нужно многопоточное приложение, вы должны либо расширить класс Thread, либо реализовать интерфейс Runnable. Начинающие никогда не понимают, в чем разница (если она есть), но, чтобы добавить путаницы, им также говорят всегда запускать поток с помощью метода запуска, а не использовать метод запуска. Или подождите, было ли наоборот? Ведь не беда, все равно не стоит запускать поток вручную, это слишком дорого, лучше используйте пул потоков. Просто, за исключением того, что это не так.

К счастью, в Kotlin есть еще более простое решение, называемое сопрограммами. Проще говоря, сопрограммы позволяют очень быстро писать асинхронный неблокирующий код. Основная идея состоит в том, чтобы иметь функции, которые можно приостановить; другими словами, вычисление может быть приостановлено в какой-то момент и возобновлено позже. Самое приятное то, что при написании неблокирующего кода модель программирования на самом деле не меняется, поэтому написание неблокирующего кода практически не отличается от написания блокирующего кода. Давайте посмотрим два примера:

 fun sendRequest(): Int { /* do some heavy work */ return 1; }

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

 suspend fun sendRequest(): Int { /* do some heavy work */ return 1; }

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

Асинхронный сервис с Ktor

Когда дело доходит до написания REST API, необходимо предпринять несколько дополнительных шагов, таких как запуск встроенного сервера или анализ запроса, и, конечно же, никто не хочет делать это вручную. В Java есть Spring Boot, что очень упрощает задачу, и, к счастью, в Kotlin есть фреймворк под названием Ktor. Ktor — это веб-фреймворк для создания асинхронных серверов. Как говорится на веб-сайте, Ktor «прост в использовании, интересен и асинхронен». Теперь удовольствие субъективно, поэтому я не хотел бы доказывать это, тем не менее, давайте посмотрим фрагмент, который оказывается простым в использовании и асинхронным.

 fun main() { embeddedServer(Tomcat, 8080) { routing { get { call.respond("Hello world!") } } }.start(wait = true) }

В приведенном выше примере представлен полнофункциональный сервер Kotlin Ktor, который работает на встроенном сервере Tomcat, прослушивает порт 8080 и асинхронно отвечает «Hello world!» для получения запросов. Все это менее чем в 10 строках кода.

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

Другие преимущества Kotlin на серверной части

Первое преимущество, на которое я хотел бы обратить внимание, это то, что вы можете использовать библиотеки Java в Kotlin, и, поверьте мне, существует множество замечательных сторонних библиотек для Java, которые могут сделать вашу жизнь проще. Зачем вам писать свою собственную реализацию, когда есть готовая к использованию библиотека с открытым исходным кодом, которая отлично справляется со своей задачей? Использование их с Kotlin работает безупречно.

Еще одним важным преимуществом Kotlin и Ktor являются обширные библиотеки и среды тестирования, которые вы можете использовать. Фреймворк Junit отлично работает с Kotlin, и Ktor добавляет к этому свою собственную библиотеку тестирования, которая позволяет вам писать сквозные тесты и интеграционные тесты в кратчайшие сроки. Вы можете использовать собственный тестовый движок, который будет запускать все ваше приложение и может обрабатывать запросы так же, как это делало бы живое приложение.

Заключение

Как я упоминал ранее, я в первую очередь являюсь бэкенд-разработчиком Java, за плечами у меня несколько серверных приложений и REST API. Хотя я люблю программировать на Java, я думаю, что не существует единственного лучшего языка или фреймворка, который бы идеально подходил для любой работы и мог решить любую проблему. Мой подход заключается в том, чтобы ознакомиться с как можно большим количеством инструментов и, когда возникает проблема, выбрать лучший инструмент, который может безупречно решить эту конкретную проблему.

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