Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Simple and modern server-side engineering with ...

Simple and modern server-side engineering with Kotlin

Takahito Yamada
LINE SP Dev 1Team Software Engineer
https://linedevday.linecorp.com/jp/2019/sessions/S1-13

LINE DevDay 2019

November 20, 2019
Tweet

More Decks by LINE DevDay 2019

Other Decks in Technology

Transcript

  1. 2019 DevDay Simple and Modern Server-Side Engineering With Kotlin >

    Takahito Yamada > LINE SP Dev 1Team Software Engineer
  2. > 2019 > Go / Ruby / Python  

    3 > Perl, Kotlin   (  )
  3. Agenda > Server-side Kotlin in LINE > The Advantage of

    Server-side Kotlin > Server-side Kotlin Pitfalls
  4. How much is Kotlin used in LINE? 90% 10% 0

    50 100 150 200 250 300 350 400 450 2018.01 2019.01 2019.10 Kotlin Java
  5. Why Kotlin > Java Interoperability Interoperability of existing Java projects,

    knowledge and infrastructures > Low Learning Cost Easy to understand for Java developers
  6. Application Framework > Used by existing java projects > Add

    kotlin-spring plugin for opening classes and methods > Official support from Spring Framework 5.0 plugins { // Kotlin Version 1.3.41 id "org.jetbrains.kotlin.plugin.spring" version "1.3.41" // Spring Boot Version 2.1.5.RELEASE id "org.springframework.boot" version "2.1.5.RELEASE" // Dependency Manager id "io.spring.dependency-management" version "1.0.8.RELEASE" } Kotlin
  7. OR Mapper > Mapper annotation compatible with here document and

    embodied string @Select(""" SELECT * FROM campaigns WHERE id = #{id} AND incentive_id = #{incentiveId} """) fun find(id: Long, incentiveId: Long): CampaignEntity? Kotlin
  8. @Select("SELECT" + " * " + " FROM " +

    " campaigns " + " WHERE " + " id = #{id} " + " AND " + "incentive_id = #{incentiveId} ") public CampaignEntity find(long id, long incentiveId): Java OR Mapper @Select("SELECT * FROM campaigns WHERE id = #{id} AND incentive_id = #{incentiveId}") public CampaignEntity find(long id, long incentiveId): Java
  9. > Conciseness Release from the verbosity of Java > Type

    Safe Compiler validates types and checks null while compiling > Few New Concepts The cherry pick from other languages Pragmatic Language [1] https://leanpub.com/effectivekotlin/
  10. Extension null value JsonNode. get("key") key isn’t found value is

    null JsonNode .Null key, value found val node = mapper.readTree(json) val value = node.get("scheme") if (value != null){ if (!value.isNull){ ... } } verbose Kotlin
  11. Extension null value JsonNode. getOrNull("") fun JsonNode.getOrNull(name: String): JsonNode? {

    val v: JsonNode? = this.get(name) return when { v == null || v.isNull -> null else -> v } } key isn’t found value is null null key, value found Kotlin extention
  12. Null Safety var str: String? = "hello" str = null

    var str: String = "hello" str = null OK Nullable Type Non-Null Type Task :compileKotlin FAILED
  13. Null Safety var str: String? = "hello" str.length var str:

    String = "hello" str.length OK Nullable Type Non-Null Type Task :compileKotlin FAILED
  14. Null Safety Null Safety Infrastructure Web, Redis, DB… Domain Domain

    Model Use cases Business Logic Validation fun update(id: Int, req: Request) : User{ if (req.imageUrl != null){ val userEntity = userRepo.findById(id) userRepo.update(name = req.name) return User(userEntity) } } null check everywhere
  15. Null Safety data class SpCampaignRequest( @field:JsonProperty("id") val spCampaignId: Long, val

    campaignUrl: String, val imageUrl: String? ) Nullable / Not Null fun getCampaigns(): List<CampaignProtocol>? = redisTemplate.opsForValue().get(CAMPAIGNS_KEY) Return value is Nullable Null Safety Infrastructure Web, Redis, DB… Domain Domain Model Use cases Business Logic Validation + Type
  16. Platform Type > Platform Type Not null safety Relaxed null

    check 1. Set annotation to Java 2. Use Platform type as Nullable
  17. Jackson Kotlin data class CampaignResponse( val id: Int, val startAt:

    Int, val endAt: Int, val isNew: Boolean ) JSON { "id": 1, "startAt": 1572506387, "endAt": 1572506387, "new": true } new isNew
  18. Jackson Java public final class CampaignResponse { ... public final

    int getId() { return id; } ... } JSON { "id": 1, "startAt": 1572506387, "endAt": 1572506387, "isNew": true } getter
  19. Jackson Java Class public final class CampaignResponse { ... public

    final boolean isNew() { return idNew; } ... } JSON { "id": 1, "startAt": 1572506387, "endAt": 1572506387, "new": true } Kotlin data class CampaignResponse( val id: Int, val startAt: Int, val endAt: Int, val isNew: Boolean ) getter?
  20. Jackson Kotlin data class CampaignResponse( val id: Int, val startAt:

    Int, val endAt: Int, @get:JsonProperty("isNew") val isNew: Boolean ) JSON { "id": 1, "startAt": 1572506387, "endAt": 1572506387, "isNew": true } annotation
  21. Summery > Server-side Kotlin in LINE Server-side Kotlin is used

    more and more in LINE > The Advantage of Kotlin Concise and null safety > Server-side Kotlin Pitfalls Be careful Platform Type when you use java library