Parsování času z requestu pomocí Jackson v Kotlinu

Pokud vytváříte restovou službu a používáte Spring Boot s Kolinem, je pravděpodobné, že časem budete potřebovat parsovat čas z requestů. Nejdříve je třeba přidat závislost:

implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.7")

Ukázky anotací a requestů

Číst dálParsování času z requestu pomocí Jackson v Kotlinu

Funkce groupBy v Kotlinu

Kotliní standardní klihovna nabízí funkce pro groupování elementů kolekcí. Základní groupBy() funkce přijímá lambdu a vrací mapu. V této mapě je každý klíč (key) výsledkem lambda funkce a hodnota (value) je seznam elementů z kolekce podle daného klíče.

    val names = listOf("Petr", "Jan", "Marie", "Matouš", "Petra", "Soňa", "Patricie")

    println(names.groupBy { it.first() })
    println(names.groupBy(keySelector = { it.first() }))
    // {P=[Petr, Petra, Patricie], J=[Jan], M=[Marie, Matouš], S=[Soňa]}

    println(names.groupBy { it.length })
    println(names.groupBy(keySelector = { it.length }))
    // {4=[Petr, Soňa], 3=[Jan], 5=[Marie, Petra], 6=[Matouš], 8=[Patricie]}

    println(names.groupBy(keySelector = { it.length }, valueTransform = { it.toUpperCase() }))
    // {4=[PETR, SOŇA], 3=[JAN], 5=[MARIE, PETRA], 6=[MATOUŠ], 8=[PATRICIE]}

    println(names.groupBy(keySelector = { it.substring(0, 2) }, valueTransform = { if (it.length == 4) it.toUpperCase() else it.toLowerCase() }))
    // {Pe=[PETR, petra], Ja=[jan], Ma=[marie, matouš], So=[SOŇA], Pa=[patricie]}

Číst dálFunkce groupBy v Kotlinu

Redis health check

Většinou není problém s připojením k redis databázi. Ani když používáte docker image a contejner s redisem zastavíte. Po jeho spuštění se aplikace zase korektně připojí do redis databáze. Měl jsem ale problém v případě kubernetu, kdy po znovu nasazení a spuštění docker kontejneru s redisem se aplikace nemohla sama připojit. Řešením bylo udělat health actuator a v případě, že je down, aplikaci restartovat. Jako klienta používám redisson.

import org.redisson.api.RedissonClient
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.actuate.health.Health
import org.springframework.boot.actuate.health.ReactiveHealthIndicator
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono

@Component
class RedisHealthChecker : ReactiveHealthIndicator {
    private val log = LoggerFactory.getLogger(RedisHealthChecker::class.java)

    @Autowired
    lateinit var redissonClient: RedissonClient

    override fun health(): Mono {
        return try {
            val bucket = redissonClient.getBucket("healthBucket")
            bucket.set("Ok")
            Mono.just(Health.Builder().up().build())
        } catch (e: Exception) {
            log.error("Error in redis connection", e)
            Mono.just(Health.Builder().down().build())
        }
    }
}

Kotlin let není if

Konstrukce ?.let {} ?: run {} se sice používá jakoby místo if - else, ale není s ní zaměnitelná. Pokud máte nullable objekt, použitím ?.let {} zpracujete případ, kdy je not null a ?: run {} v případě, že je null. Dalo by se říct, klasické if – else. Níže je ukázka. Vytvoříme outer a inner mapu, inicializujeme jí a pak máme dva bloky. První s if – else a druhý s ?.let a ?: run. V blocích jde o to, že nejdříve se zkusí vytáhnout hodnota pro klíč z outer mapy a pokud je hodnota nalezena, totéž proběhne pro inner mapu.

Číst dálKotlin let není if