Używanie Kotlina do tworzenia zaplecza: szybki przegląd

Opublikowany: 2022-03-11

Nie muszę przedstawiać Kotlina rodzimym programistom Androida, ponieważ w maju 2017 roku Google ogłosił, że będzie to oficjalny język rozwoju Androida. Od tego czasu zyskał dużą popularność jako główny wybór języka do tworzenia nowych i błyszczących aplikacji na Androida. Rozwiązuje wiele bolączek Javy, więc nowe aplikacje są w większości pisane w nim, a stare są w nim przepisywane.

Nie ma wątpliwości, że świetnie sprawdza się na front-endowej stronie aplikacji, a kiedy po raz pierwszy wspomina się o Kotlinie, większość ludzi kojarzy go z systemem operacyjnym Android. Jednak w tym artykule chciałbym opowiedzieć o Kotlinie jako języku zaplecza i chciałbym podzielić się moją historią o tworzeniu szybkiego, niezawodnego i asynchronicznego zaplecza Kotlina dla mojego projektu hobbystycznego na Androida. Nie będę omawiał, o co chodzi w projekcie, ponieważ wykracza to poza zakres tego artykułu; skoncentruję się raczej na wyjaśnieniu, dlaczego wybrałem Kotlin i dlaczego uważam, że jest to świetny język do pisania aplikacji serwerowych lub API REST.

Dlaczego Kotlin?

Wrócę do samego początku mojej podróży. Zawsze miałam ambicje przedsiębiorcze i myślałam, że pierwszym krokiem na tej drodze jest stworzenie czegoś samemu. Nic wielkiego, nic nie zmieniającego świata, po prostu coś małego, z czego ja i być może moja rodzina i przyjaciele możemy korzystać. Po tym, jak wpadłem na rozsądny pomysł, wskoczyłem do niego i zacząłem go wdrażać. Pierwszą rzeczą, którą robisz na początku każdego projektu, jest wybór narzędzi. W końcu odpowiedni zestaw narzędzi może na dłuższą metę zaoszczędzić dużo czasu i pieniędzy. Więc to właśnie zrobiłem.

Jestem przede wszystkim programistą Java. Napisałem kilka systemów zaplecza i interfejsów API REST przy użyciu Javy i Springa i uważam, że te dwa są świetnymi narzędziami do robienia takich rzeczy. Java sama w sobie jest obszernym językiem, ale w połączeniu ze Springiem nie ma niczego, czego nie można by zaimplementować.

Jednak w zupie jest tylko jeden maleńki włosek. Gadatliwość. Chociaż Spring i najnowsze wersje Javy bardzo w tym pomagają, nadal musisz poradzić sobie z wieloma szablonowymi kodami. I jak kiedyś powiedział mi świetny facet - najbezpieczniejszym, najbardziej niezawodnym i wolnym od błędów kodem jest kod, który nie jest spisany. Weźmy na przykład tę banalną klasę 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; } }

Moim zdaniem jest to dużo kodu na proste powiedzenie: „Chcę klasę z dwoma polami tylko do odczytu”. Najgorsze jest to, że konstruktor i metody zostały wygenerowane automatycznie. Mimo to, kiedy przeglądasz żądanie ściągnięcia, zawsze je przeglądasz, ponieważ, cóż, nigdy nie wiesz, czy są one tym, czego potrzebujesz, czy nie. Jasne, można to skrócić za pomocą bibliotek innych firm, takich jak Lombok, ale czy nie byłoby miło, gdybyśmy mogli to zrobić po wyjęciu z pudełka? Zobaczmy dokładnie tę samą klasę w Kotlinie:

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

To zdecydowanie krótsze i prostsze. Zmienne są ostateczne, ponieważ używamy słowa kluczowego val ; Konstruktor i gettery są generowane w czasie kompilacji. Jeśli wolimy nie mieć niezmiennego obiektu person, możemy po prostu zmienić val na var , i voila, mamy zmienną osobę i wszystko, co musimy zrobić, to zmienić tylko jedną literę.

Moją drugą ulubioną częścią w prostej klasie Java POJO jest przesłonięte equals() i hashCode() . Są one ponownie generowane automatycznie przez większość czasu, ale zawsze musisz je przejrzeć, aby się upewnić. Dobra wiadomość jest taka, że ​​Kotlin też sobie z tym poradzi. Po prostu zmień swoją class na data class , a otrzymasz equals() i hashCode() po wyjęciu z pudełka.

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

Krótko mówiąc, mimo że kocham Javę, chciałem jak najszybciej stworzyć minimalny opłacalny produkt dla mojego projektu. A w przypadku tworzenia oprogramowania najprostszym sposobem na osiągnięcie tego jest pisanie mniej kodu. W ten sposób moje poszukiwania lepszego języka do tworzenia back-endu trwały. Mając to na uwadze, najpierw przerzuciłem się na Node.js. Ma kilka znaczących zalet — kilka linii i serwer Express działa, nasłuchuje na porcie 8080 i odpowiada za pomocą Hello World! za każdym razem, gdy wysyłasz żądanie pobrania.

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

Łatwo, prosto i szybko. Dokładnie to, czego można oczekiwać od jednego z najpopularniejszych języków programowania. Lubię pracować z JavaScriptem i przez chwilę myślałem, że znalazłem odpowiednie narzędzie, ale potem prześladował mnie fakt, że JavaScript jest wpisywany dynamicznie. Nie zrozum mnie źle, myślę, że dynamiczne pisanie jest świetne w interfejsie, ale z mojego doświadczenia wynika, że ​​statycznie pisany back-end po prostu daje dodatkową pewność, że serwer jest mniej podatny na awarie w czasie wykonywania z powodu niezgodności typów . I bądźmy szczerzy, kiedy twój backend obsługuje kilkaset tysięcy użytkowników, naprawdę nie chcesz, aby tak się stało. Node.js oferował jednak jedną świetną funkcję, którą chciałem zachować, a mianowicie możliwość łatwego pisania asynchronicznego kodu i usług.

Mając na uwadze te wymagania, zdecydowałem się napisać mój back-end Kotlin dla Androida również w Kotlin.

Kotlin: szybki przegląd

Dla tych z Was, którzy nigdy wcześniej o tym nie słyszeli, Kotlin jest językiem programowania typu open source, statycznie typowanym, który obsługuje zarówno programowanie obiektowe, jak i funkcjonalne. Zapewnia podobną składnię i koncepcje jak C#, Java lub Scala i jest ukierunkowana głównie na JVM, ale ma również warianty, które są ukierunkowane na JavaScript lub kod natywny. Jest bardzo podobny do Javy, ponieważ Kotlin / JVM kompiluje się do kodu bajtowego Java, więc dla tych inżynierów zaplecza, którzy mają doświadczenie w JVM, Kotlin będzie łatwy do zrozumienia.

Jak podaje jego oficjalna strona, celem Kotlina nie jest bycie wyjątkowym, ale czerpanie inspiracji i najlepszych praktyk z dziesięcioleci rozwoju języka. Może być używany z dowolnym Java IDE lub z wiersza poleceń, ale osobiście wolę i polecam używanie go z IntelliJ. Jest aktywnie utrzymywany i aktualizowany przez zespół JetBrains i nie martw się o zakup wersji płatnej — jeśli dopiero zacząłeś korzystać z Kotlina, wersja społecznościowa IntelliJ zaspokoi wszystkie Twoje potrzeby. Trzy najważniejsze aspekty Kotlina, na które chciałbym zwrócić uwagę, to to, że jest: a) zwięzły (drastycznie redukuje kod wzorcowy), b) bezpieczny (po pierwsze, jest zbudowany w celu uniknięcia wyjątków zerowego wskaźnika) i c ) interoperacyjny (możesz wykorzystać istniejące biblioteki dla JVM, Androida lub przeglądarki).

Współprogramy Kotlina

Każdy chce mieć usługi, które szybko służą użytkownikom. Aby osiągnąć maksymalną pojemność serwera, pierwszą rzeczą, którą możesz zrobić, jest posiadanie aplikacji wielowątkowej. Java jest z tym dość kłopotliwa. Kiedy uczysz się języka Java, najpierw dowiadujesz się, że jeśli potrzebujesz aplikacji wielowątkowej, powinieneś rozszerzyć klasę Thread lub zaimplementować interfejs Runnable. Początkujący nigdy tak naprawdę nie rozumieją, na czym polega różnica (jeśli istnieje), ale aby zwiększyć zamieszanie, mówi się im również, aby zawsze rozpoczynać wątek metodą run, nigdy nie używać metody start. Albo poczekaj, czy było odwrotnie? W końcu to nie ma znaczenia, i tak nie należy uruchamiać wątku ręcznie, jest to zbyt drogie, raczej korzystać z puli wątków. Proste, tyle że tak nie jest.

Na szczęście Kotlin ma jeszcze prostsze rozwiązanie zwane współprogramami. Mówiąc najprościej, współprogramy umożliwiają pisanie asynchronicznego, nieblokującego kodu w bardzo płynny sposób. Główną ideą jest posiadanie funkcji, które można zawiesić; innymi słowy, obliczenia mogą zostać w pewnym momencie zawieszone i wznowione później. Najlepsze jest to, że podczas pisania kodu nieblokującego model programowania tak naprawdę się nie zmienia, więc pisanie kodu nieblokującego jest zasadniczo tym samym, co pisanie kodu blokującego. Zobaczmy dwa przykłady:

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

Ten przykład pokazuje funkcję blokującą. Wątek wykonujący ten fragment kodu nie wykona żadnej innej pracy, dopóki funkcja nie powróci, co w przypadku wywołania API lub bazy danych może zająć kilka sekund. Naprawdę nie chcemy blokować naszego wątku podczas oczekiwania na inną usługę, więc zmieńmy tę funkcję na nieblokującą.

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

Ten przykład pokazuje, jak możemy zmienić naszą metodę w funkcję nieblokującą, którą można zawiesić. Oznacza to, że jeśli, dla uproszczenia, ciężką pracą jest proste wywołanie funkcji delay() przez 10 sekund, wątek wykonujący będzie przez ten czas pracował nad innymi zadaniami i wznowi wykonywanie funkcji po upływie 10 sekund. Ładny, nieblokujący kod uzyskany za pomocą jednego słowa kluczowego.

Usługa asynchroniczna z Ktor

Jeśli chodzi o pisanie REST API, trzeba wykonać kilka dodatkowych kroków, takich jak uruchomienie wbudowanego serwera lub parsowanie żądania, i oczywiście nikt nie chce tego robić ręcznie. Java ma Spring Boot, co czyni wszystko naprawdę łatwym, i na szczęście Kotlin ma framework o nazwie Ktor. Ktor to webowy framework do budowania asynchronicznych serwerów. Jak podaje jego strona internetowa, Ktor jest „łatwy w użyciu, zabawny i asynchroniczny”. Teraz zabawa jest subiektywna, więc nie chciałbym tego udowadniać, jednak zobaczmy fragment, który okaże się łatwy w użyciu i asynchroniczny.

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

Powyższy przykład przedstawia w pełni funkcjonalny serwer Kotlin Ktor, który działa na wbudowanym serwerze Tomcat, nasłuchuje na porcie 8080 i odpowie asynchronicznie „Hello world!” aby otrzymać prośby. Wszystko to w mniej niż 10 liniach kodu.

Ktor może oczywiście znacznie więcej. Przedstawienie wszystkich funkcji Ktora wymaga osobnego artykułu, ale między innymi sprawia, że ​​logowanie i uwierzytelnianie są dziecinnie proste. Przeczytaj więcej o tym, co Ktor może zrobić po stronie serwera i jak to skonfigurować tutaj.

Inne zalety Kotlina na zapleczu

Pierwszą korzyścią, na którą chciałbym zwrócić uwagę, jest to, że możesz używać bibliotek Java w Kotlin i zaufaj mi, istnieje wiele niesamowitych bibliotek innych firm dla Javy, które mogą ułatwić Ci życie. Po co pisać własną implementację, skoro istnieje gotowa do użycia biblioteka typu open source, która doskonale spełnia swoje zadanie? Używanie ich z Kotlinem działa bezbłędnie.

Kolejną ważną zaletą Kotlin i Ktor są obszerne biblioteki testowe i frameworki, z których możesz korzystać. Framework Junit działa jak urok z Kotlinem, a Ktor dodaje do tego własną bibliotekę testową, która pozwala na pisanie kompleksowych testów i testów integracyjnych w krótkim czasie. Możesz użyć niestandardowego silnika testowego, który będzie uruchamiał całą aplikację i może obsługiwać żądania, tak jak robiłaby to aplikacja na żywo.

Wniosek

Jak wspomniałem wcześniej, jestem przede wszystkim programistą back-end w Javie, mającym za sobą kilka aplikacji serwerowych i interfejsów API REST. Chociaż uwielbiam programować w Javie, uważam, że nie ma jednego najlepszego języka lub frameworka, który byłby idealny do każdej pracy i mógł rozwiązać każdy problem. Moje podejście polega na zapoznaniu się z jak największą liczbą narzędzi, a gdy pojawi się problem, wybierz najlepsze narzędzie, które bezbłędnie rozwiąże dany problem.

Jak podaje strona Kotlin, celem Kotlina nie jest bycie wyjątkowym; zamiast tego czerpie inspirację i najlepsze praktyki z dziesięcioleci rozwoju języka i wierzę, że jeśli chodzi o rozwój zaplecza, Kotlin, Coroutines i Ktor tworzą niesamowite trio do wykonania tej pracy. Więcej o Kotlinie i jego przydatności jako języka programowania przeczytasz tutaj.