Изграждане на уеб сървъри с 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.