Изграждане на уеб сървъри с Kotlin
На този етап вярвам, че повечето програмисти са чували за Kotlin и чудесата, които носи в JVM средата. Основната причина, поради която програмистите използват Kotlin, е разработката на Android. Kotlin пусна кодова база за разработване на предни уебсайтове чрез конвертиране на кода на Kotlin в JavaScript; обаче, както аз го виждам, това се прие много добре и мисля, че и вие ще се съгласите.
Бях присъствал на Google DevFest в Лондон преди няколко месеца и някои от експертите на Kotlin изразиха любовта си към Kotlin за изграждане на уеб сървъри. Въпреки че мислех да създам бекенд услуги с помощта на Kotlin, всъщност никога не съм го научил досега.
Мисленето за това сега има смисъл, защото Kotlin процъфтява по-добре като back-end език, отколкото като front-end. Java Servlets и JSP бяха доста известни навремето (някои компании все още ги използват). Spring Boot също беше популярен избор за използване в проекти за изграждане на сложни приложения в Java. Kotlin, като производно на Java, също трябва да бъде страхотен език за писане на back-end код.
Има множество рамки, които ви позволяват да създавате сървъри в Kotlin, като Javalin, http4k и Spring boot. Заех се да науча Ktor и ето защо трябва да обмислите да научите Ktor също.
Развитието в Ktor е лесно
Можете ли да си представите свят, в който все още ще пишем програмиране с 0s и 1s? Или можете да си представите след десетилетия на програмиране, ние все още ще използваме асемблера като наш основен език? Не точно. С напредването на технологиите трябва да добавим абстракция към нещата, които вече сме измислили.
Ktor е брилянтен в предоставянето на дълбоки нива на абстракция с помощта на „плъгини“. Ktor има плъгини за почти всичко, от което се нуждаете, за да разработите back-end уеб приложение.
Документация на Ktor
Документацията на Ktor е изключително удобна за начинаещи, тъй като обяснява всичко до най-малкия детайл. Документацията обхваща всичко от оторизация, маршрутизиране, уеб сокети и шаблони. Ще говоря за някои от добавките от документацията.
Ктор Маршрут
Всяко уеб приложение се нуждае от маршрути. Указването на маршрути в Ktor включва инсталиране на плъгина Route и създаване на маршрути. В зависимост от това как настройвате проекта си, вашият код ще изглежда приблизително така (използвах Netty двигателя с конфигурационния файл HOCON)
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { routing { get("/") { call.respond(HttpStatusCode.OK, "Hello from Ktor") } } }
Регистриране на обажданията на Ktor
По същия начин, с функцията install
е лесно да добавите прехващачи за регистриране към извикванията на заявки, направени към сървъра. Това също включва инсталиране на зависимостта CallLogging
gradle.
implementation("io.ktor:ktor-server-call-logging-jvm:$ktor_version") fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { install(CallLogging) { level = Level.INFO filter { call -> call.request.path().startsWith("/") } } routing { get("/") { call.respond(HttpStatusCode.OK, "Hello from Ktor") } } }
Ktor сериализация
Тъй като по-голямата част от информацията се прехвърля от JSON, имаме нужда от начин да ги анализираме в класовете данни на Kotlin и обратно. Това става чрез добавяне на зависимостта и инсталиране на плъгина ContentNegotiation, предоставен от Ktor.
implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version") implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version") fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { install(CallLogging) { level = Level.INFO filter { call -> call.request.path().startsWith("/") } } install(ContentNegotiation) { json() } routing { get("/") { call.respond(HttpStatusCode.OK, "Hello from Ktor") } } }
Ktor Шаблони
Ако вашият сървър обслужва и уеб страници на клиента, добра идея е да имате някакъв вид рамка за шаблони. За щастие Ktor има множество опции за шаблони, от които да избирате, но моят любим е HTML и CSS DSL.
fun main() { val htmlContent = html { head { title { +"This is Kotlin DSL" } style { css(".color-red") { color = "#ff0000" } css("h1") { cursor = "pointer" fontSize = "2.5rem" } } } body { h1 { +"Heading 1 is 2.5rem big." } p(className = "color-red") { +"Red" b { +" and bold" } } } } println(htmlContent) }
Можете да прочетете повече за DSL тук:
Защо да използвате Ktor пред други алтернативи?
Причината, която ми блести най-много, е, че Ktor е базиран извън Kotlin. Kotlin е многопарадигмен език с различни функции, които подобряват продуктивността на разработчиците.
„Модерен език за програмиране, който прави разработчиците по-щастливи.“ — Уеб страница на JetBrains Kotlin.
Корутини на Kotlin
Рамката на Ktor е изцяло изградена върху идеята за преустановени функции и съпрограми. Корутините са леки операции, подобни на нишки, които се изпълняват асинхронно.
Kotlin Null Safety
Kotlin, подобно на Haskell, реши да проектира езика, който не прави нищожността имплицитно свойство на обектите. Екземплярите могат да сочат към null
само ако типът е допълнен с въпросителен знак ?
. IntelliJ IDEA също ви предупреждава, ако забравите да проверите дали обектът може да е нула. Операторът за безопасно повикване ?.
или операторът elvis ?:
добавя към извършването на безопасни нулеви проверки.
// Converting request body JSON to AuthSignInRequest data class // Incase of failure, receiveNullable will return null // The null case is handled by the elvis operator. val request = call.receiveNullable<AuthSignInRequest>() ?: run { call.respond(HttpStatusCode.BadRequest, "Check your request body") return@post }
Разширени функции на Kotlin
Признавам, че излъгах в горните кодови фрагменти. Никога няма да пишете код в Ktor, така че всичко да е фиксирано в една единствена module
функция. Можете да разделите кода си на множество функции, което може да се направи чисто с помощта на функциите за разширение. Обърнете внимание, че функцията module
също е разширение на Application, което прави идентичността на двигателя Netty начален код.
// Application.kt // imports fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { // Extension function configureMonitoring() // Callable since it is an Application extension configureSerializable() configureRouting() // functions present in other files. } // Routing.kt package plugins // imports fun Application.configureRouting() { routing { // public function in the Application class. route("/auth") { // Extension Lambda function (see below) signInRoute() } indexRoute() // Route handlers in other files. } } /* * routing is defined as * fun Application.routing(configuration: Routing.() -> Unit): Routing * configuration is an extension lambda parameter */ // AuthRoutes // imports fun Route.signInRoute() { post("/signIn") { // post is a function of Route class // suspended lambda function executed in Coroutines } }
Какво следва? Има много неща за изследване на Ктор. Инжектирането на зависимости с помощта на Koin е популярно мнение за големи кодови бази на Ktor. Интеграцията на базата данни на Ktor е мощна с Exposed за PostgreSQL или KMongo за MongoDb. Ако търсите да правите API извиквания във вашия сървър или в друг проект на Kotlin (приложение за Android), можете да обмислите използването на ktor-client, библиотека на Kotlin, за да направите мрежовите повиквания преобладаващи в мултиплатформените мобилни приложения на Kotlin. Можете да прочетете повече за това тук:
If you wish to read every article from me, consider joining the Medium program with this referral link. Want to connect? My GitHub profile. My Portfolio website.