10年前のレガシーシステムをサーバーサイドKotlinでフルリニューアルしている話 #jjug_ccc #ccc_g2

10年前のレガシーシステムをサーバーサイドKotlinでフルリニューアルしている話 #jjug_ccc #ccc_g2

JJUG CCC 2017 Fall での発表資料です
◆githubにサンプルプロジェクトあげてます
https://github.com/maeharin/kotlin-dvd-rental-dev

◆Kotlinのイベント「どこでもKotlin」を開催してます!
https://m3-engineer.connpass.com/event/70561/

0ff63a1cf64b2501566f37581000bd9b?s=128

Hidenori Maehara

November 18, 2017
Tweet

Transcript

  1. 2.

    • 前原 秀徳 • @maeharin(まえはりん) • エムスリー株式会社 • エンジニアチームリーダー、グループ会社取締役等を歴任 •

    好きな言語等:Kotlin、Ruby、Vue.js • 好きな漫画:ベルセルク(心の支え。悩んだら読む) • 自慢:ブログ記事が、はてぶ1200超えた ◦http://maeharin.hatenablog.com/ 自己紹介
  2. 13.

    主要システム Ruby on Rails • ビジネス上優先度の高いシステムはRuby on Rails • 優先度低いシステムは10年前のシステム

    ◦ → だが、この部分の優先度が高まってきた 10年前の Javaシステム 7年前の Javaシステム 原因2: 10年前のシステムが... Javaの独自FW viewの部分はXSLT!
  3. 21.

    5月 6月 7月 8月 9月 10月 11月 12月 1月 2月

    3月 12月上旬に 10年前の部分の リニューアルを リリース! 今の進捗 開発 ▲プロトタイプ作成 ▲経営会議承認 ▲リリース1 開発 ▲リリース2 ▼NOW ※ エンジニア3名で頑張ってます
  4. 28.

    • 私がRuby on Railsで全部で作った • UIにはVue.jsやmaterial-components-webを使用 • 早期にリスクを発見できることも • 自分への自信

    → 経営陣への説得力 3. プロトタイプで不確実性をコントロールした 言葉は無粋!!押し通れ!! by ベルセルク
  5. 30.

    • APIサーバー ◦ 重複ロジック・DBを一元化したい ◦ 型を用いてカッチリとやりたい • フロントサーバー ◦ 複数のサービスがある

    1. メインサイト(Rails、1年前にリプレイス済) 2. サテライトサイト(Java、7年もの...) 3. 管理画面:3種類(Java、10年もの...) ◦ 頻繁に改修が入る ◦ リッチなUIへのニーズが強い 技術選定のポイント
  6. 35.

    Kotlinとは Kotlin • 静的型付けオブジェクト指向言語 • いわゆる「JVM言語」 • 開発元:JetBrains • 2016年2月に正式リリース

    ◦ 2017/11/18 現在、ver1.1.60 • Apache License ver2.0 • 特に、Google I/O 2017以降、爆発的な広がり
  7. 41.

    • 型:あり(型推論、null safetyも嬉しい) • エムスリーにはたろう (@ngsw_taro) がいる! • フレームワーク:Spring Boot(問題なし)

    • Java製の社内ライブラリは使えるか:使える • IDE:IntelliJ IDEA • 学習コスト:RubyENGは親しみやすい構文(後述) Kotlin選択理由 Kotlin Webアプリケーション 新しいサーバサイドプログラミング 絶賛発売中! エムスリー株式会社 日本Kotlinユーザーグループ代表 長澤 太郎 たろう(@ngsw_taro) • 言語の将来性:きっとある(Google I/O 2017)
  8. 42.

    Ruby Kotlin a.map {i -> i * 10} a.reduce {sum,n

    -> sum + n} a.groupBy {i -> i % 2} a.filter {i -> i % 2 == 0} a.map {|i| i * 10} a.reduce {|sum,n| sum + n} a.group_by {|i| i % 2} a.select {|i| i % 2 == 0} (参考)Rubyエンジニアに親しみやすい構文
  9. 46.
  10. 49.
  11. 51.
  12. 55.

    postgresql ElasticSearch customer-front admin-front api APIクライアントgem swagger-codegenで自動生 成 サンプルプロジェクトの構成 Kotlin:

    1.1.60 Spring Boot: 1.5.8 spring-security-oauth2: 2.2.0 doma: 2.18.0 rails: 5.1.4 vue: 2.5.3 element-ui: 2.0.4 typescript: 2.6.1 rails: 5.1.4
  13. 60.

    package com.example.demo.controller import org.springframework.web.bind.annotation.* @RestController class HelloController { @GetMapping fun

    index():String = "hello!" } Kotlinで書く hello world 2) KotlinでRestControllerを作成
  14. 64.

    @RestController @RequestMapping("/api/v1/films") class FilmRestController( private val filmRepository: FilmRepository ) {

    @GetMapping fun index(): List<FilmResource> = ... @PostMapping fun create( @RequestBody @Validated filmParam: FilmParam Springのアノテーション • 問題なく使える
  15. 65.

    @Configuration @EnableAuthorizationServer class Oauth2AuthorizationServerConfig( private val authManager: AuthenticationManager, private val

    dataSource: DataSource ) : AuthorizationServerConfigurerAdapter() { @Bean fun passwordEncoder(): BCryptPasswordEncoder = BCryptPasswordEncoder() spring-security-oauth2 • 問題なく使える
  16. 68.

    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}") apply plugin: 'kotlin' apply plugin: 'kotlin-spring' compileKotlin {

    kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } ※Spring Initializr経由で作成す るとデフォルトで入る ↑Spring Initializr経由で作成したbuild.gradle(抜粋) kotlin-springプラグイン • kotlin-springプラグインでopen不要に
  17. 70.

    data class FilmResource( var name: String = "", var isAdmin:

    Boolean = false, var companyId: Int = 0 ) Jacksonは デフォルト値ありの コンストラクタを要 求 デフォルト値は使い たくないのに。。 jackson-module-kotlin • APIリクエスト(JSON)をKotlinへマッピング
  18. 71.

    data class FilmResource( val name: String, val isAdmin: Boolean, val

    companyId: Int ) jackson-module-kotlin • こうしたい
  19. 73.
  20. 80.

    @Entity(naming = NamingType.SNAKE_LOWER_CASE) @Table(name = "film") public class FilmEntity {

    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @SequenceGenerator(sequence = "film_film_id_seq") public Integer filmId; public String title; public String description; SQL実行結果のマッピ ングと捉え、ロジックを 書かないようにした Doma 2 • Doma 2のEntity(Java)
  21. 81.

    @ConfigAutowireable @Dao public interface FilmEntityDao { @Select FilmEntity selectById(Integer filmId);

    @Select List<FilmEntity> selectAll(); @Insert int insert(FilmEntity entity); Doma 2 • Doma 2のDao(Java)
  22. 82.

    レイヤー構造 application domain infrastructure RestController ApplicationService Model, ValueObject Repository(interface) Repository(impl)

    Doma(Dao, Entity) doma-genでDBスキーマから 自動生成も可能 Kotlin Java Doma 2 よく触る部分は 全部Kotlin!
  23. 84.

    postgres ElasticSearch customer-front admin-front api APIクライアント gem swagger-codegen で自動生成 swagger-codegen

    • APIクライアントを手動で作るのは中々しんどい • swagger-codegenで自動生成できる
  24. 85.

    Spring Boot (APIサーバー) API定義ファイル(json) Swagger UI (WEB GUI) SpringFoxで API定義ファイル生成

    API定義ファイルを利用 swagger-codegen コマンド Rubyクライアント 自動生成 swagger-codegen • SpringFoxでswagger definition(json)を生成 • そのjsonをswagger-codegenに食わせる
  25. 88.

    • Kotlin x Spring BootでAPIサーバーは問題なく作れる • kotlin-springプラグインでopen不要 • jackson-module-kotlinでjsonの扱いが楽に •

    私達はDoma 2の層をJavaにした ◦→ よく触る部分はKotlin • Kotlinかわいい(^ω^)ペロペロ Kotlin APIサーバーの所感