Kotlin, Spring Boot a Heroku – Vytvorenie API (2/4)

Predošlá časť - Úvod Nasledujúca časť - Databáza

Na vytvorenie našej Spring Boot API využijeme Spring Initializr. Je to nástroj, ktorý nám pomocou jednoduchého UI dovolí nasetupovať náš nový projekt a vypľuje nám zip-ko, ktoré rozbalíme a máme vytvorený projekt. Projekt by sa dal samozrejme vytvoriť aj ručne, ale načo by sme to robili, keď máme takýto cool nástroj.

Poznámka: Projekt sa pomocou Spring Initializr dá vytvoriť aj priamo cez IDEA. Mne sa však osobne viac páči webová verzia – asi iba preto, že som s ňou začínal.

Spring Initializr

Ideme si teda nasetupovať náš Spring Boot projekt. Ako Project zvolíme Gradle Project. Debata Maven vs. Gradle je na inokedy, zvoľme Gradle, pretože s tým mám viac skúseností. Language si vyberme Kotlin, pretože chceme byť cool a Java je už stará (reálne nemám vôbec nič proti Jave). Spring Boot verziu nechajme na predvolenej hodnote (v čase písania 2.3.4). Project Metadata si vyplň podľa seba, alebo použi moje, ktoré sú nasledovné:

Group: sk.streetofcode
Artifact: passwords
Name: passwords
Description: Password Manager backend
Package name: (vypĺňa automaticky) sk.streetofcode.passwords
Packaging: Jar
Java: 11 (myslím, že ak používame Kotlin, tak je to jedno, ale nechajme 11)

Do Dependencies kvôli jednoduchosti na začiatok pridáme iba Spring Web.

Screenshot konfiguracie Spring Boot API v Spring Initializr
Konfigurácia v Spring Initializr

Môžeme kliknúť na Generate a stiahnuť si zip-ko s našim fantastickým novým projektom (ktorý dokáže akurát tak spustiť server).

Čo sme to vlastne spravili?

V dnešnej dobe väčšina frameworkov už má nejaké jednoduché nástroje na to, aby človek vedel ľahko začat vytvárať appky v danom frameworku. React má create-react-app, C# má Visual Studio, ktoré to robí už dlhšie, alebo aj CLI nástroj, Flutter na to tiež má IDE a aj CLI a tak ďalej. V minulosti by bolo potrebné všetky súbory povytvárať manuálne, hľadať správnu Gradle konfiguráciu atď. Takto máme všetko jednoducho nasetupované a nemusíme riešiť detaily na pozadí.

Naspäť k našej appke

Zip-ko si jednoducho rozbal kam uznáš za vhodné a otvor ho v nejakom editore. Vrelo odporúčam IntelliJ IDEA, ale všetko, čo budeme robiť sa dá robiť aj vo VS Code, alebo aj vo Vim-ku. Na tutoriál však budem využívať IDEA, ale keď to bude potrebné, tak spomeniem, ako danú vec vykonať cez terminál.

Poznámka: Fakt netuším, ako by som IntelliJ IDEA mal skloňovať, tak sa hrajme na to, že je to nesklonné a budem používať všade tvar IDEA (aj keď mi to trochu trhá oči).

Keď appku otvoríme v IDEA (cez File -> Open… -> navigujeme sa na náš projekt -> OK) a všetko sa nám načíta, tak by sme ju mali byť hneď schopní spustiť (cez zelenú šípku v súbore PasswordsApplication.kt). No je nám to na nič, pretože jediné, čo sa spustí je server, ktorý síce počúva na localhost:8080, ale nemá nastavené žiadne cesty a ani odpovede, takže s ním nevieme komunikovať. Nemáme žiadny Controller.

Vytvárame Controller

Controller je ako keby vstupná brána z internetu do našej aplikácie. Medzi tým je síce viacero vrstiev, ktoré sa vykonávajú pred Controller-om, ale tie nás momentálne nezaujímajú. Na to, aby sme si vytvorili Controller, stačí v src/main/kotlin/sk.streetofcode.passwords/ vytvoriť nový súbor. Či už cez IDEA alebo cez terminál. Súbor nazvime PasswordController.kt, pretože sa bude zaoberať práve heslami. Bude to náš hlavný Controller. Po vytvorení môžme súbor otvoriť.

Zatiaľ je to prázdny súbor, ktorý ma akurát definovaný package (ak sme ho vytvárali cez IDEA). Poďme to zmeniť. Vytvorme classu PasswordController:

package sk.streetofcode.passwords

class PasswordController()

Keďže sme v Kotline, tak to je všetko, čo potrebujeme na vytvorenie classy. Prázdna classa nám je ale tiež relatívne na nič. Na to, aby bola valídnym Spring Controller-om, ju musíme oanotovať anotáciou @RestController a k tomu aj anotáciou @RequestMapping, aby Spring vedel, akú cestu má k tomuto Controller-u namapovať:

package sk.streetofcode.passwords

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/passwords")
class PasswordController()

Parameter @RequestMapping anotácie nám určuje, kam sa budem v browseri musieť navigovať, aby som sa dostal k nášmu Controller-u (v našom prípade to bude localhost:8080/passwords). Prázdny Controller nám je tiež ale na nič. Musíme mu ešte pridať nejakú metódu, ktorá sa bude dať zavolať z browsera (alebo Postman-a, alebo čohokoľvek). Na test si pridáme metódku get(), ktorá proste vráti String “It works!”:

package sk.streetofcode.passwords

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/passwords")
class PasswordController {
  fun get(): String {
    return "It works!"
  }
}

Na to, aby sa táto metódka bola prístupná z browsera musíme opäť použiť anotácie – konkrétne anotáciu @GetMapping, ktorá Spring/u povie, že táto metóda má byť zavolaná, keď príde HTTP GET request na /passwords cestu:

package sk.streetofcode.passwords

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/passwords")
class PasswordController {
  @GetMapping("")
  fun get(): String {
    return "It works!"
  }
}

Mega! Keď teraz spustíme našu aplikáciu, tak dokonca už aj bude vedieť niečo robiť. Skús to. Buď v IDEA cez zelenú šípku v súbore PasswordsApplication.kt, alebo z terminálu pomocou príkazu ./gradlew bootRun.

Keď to v IDEA prvý krát spustíš cez PasswordsApplication súbor, tak ďalší krát by ti to už malo ísť spustiť cez zelenú šípku v hornom bare.

Screenshot spustenej aplikácie
It works!

Po spustení aplikácie sa skús v browseri navigovať na už spomínanú cestu localhost:8080/passwords – malo by ti vypísať „It works!“.

Vraciame heslá

Momentálne naša get() metódka vracia akurát tak String. Poďme teda upraviť celý náš PasswordController tak, aby vedel ukladať a vracať heslá.

package sk.streetofcode.passwords

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/passwords")
class PasswordController(
  private val passwords: MutableList<String> = mutableListOf()
) {
  @GetMapping("")
  fun get(): List<String> {
    return passwords
  }
}

Všimni si pridaný field passwords a zmenenú návratovú hodnotu get() funkcie. Týmto zabezpečíme, že keď zavoláme localhost:8080/passwords z browsera, tak nám to vráti nami uložené heslá. Heslá ale nevieme ešte ukladať. Tak čo nám to vráti? Nič. Spravme si teda metódku na ukladanie hesiel.

Screenshot - čo nám vráti /passwords
/passwords nám žiadne heslá nevráti

Ukladáme heslá

Metódky na ukladanie vecí sa anotujú anotáciou @PostMapping, pretože využívajú HTTP POST metódu (viac o HTTP metódach si prečítaj tu, je relatívne dôležité im pochopiť, aj keď sú iba konvenciou). Keď POST-ujeme, tak chceme zvyčajne posielať v HTTP requeste nejaké telo – body. Toto telo môže byť obyčajný text (text/plain), XML (application/xml), JSON (application/json) a ďalšie veci. Najčastejšie sa v dnešnej dobe stretneš s JSON-om. Spring Boot automaticky konvertuje JSON na objekty (ak sa dá, keď sa nedá, hodí Exception) – k tomu sa dostaneme neskôr. Zatiaľ naša metóda bude vyzerať takto:

package sk.streetofcode.passwords

import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/passwords")
class PasswordController(
  private val passwords: MutableList<String> = mutableListOf()
) {
  @GetMapping("")
  fun get(): List<String> {
    return passwords
  }

  @PostMapping("")
  fun post(@RequestBody password: String) {
    passwords.add(password)
  }
}

Easy. Môžme appku spustiť a skúsiť zavolať POST na /passwords (najjednoduchšie pomocou Postman-a…alebo CURL). Do tela requestu musím vložiť nejaký String – heslo, ktoré sa nám pridá. Keď zopár krát zavoláme POST a následne zavoláme GET, tak nám to pekne vráti všetky nami pridané heslá.

POST request z postman-a
POST request z Postman-a
GET request z Postman-a
GET request z Postman-a

Cool. Máme aspoň dačo spravené – skoro hotovú Spring Boot API. Takto sa to však bežne nerobí (skús si napr. pridať niekoľko hesiel a potom server (appku) reštartni). Na to, aby naše dáta boli natrvalo uložené sa bežne používajú databázy. V ďalšej časti sa pozrieme práve na pridávanie databázy do nášho namakaného projektu.

Kód z tejto časti tutoriálu nájdeš na našom GitHub-e.

Predošlá časť - Úvod Nasledujúca časť - Databáza


Pridaj komentár

Vaša e-mailová adresa nebude zverejnená.