$30 off During Our Annual Pro Sale. View Details »

OpenAPIによるスキーマ駆動開発を実現するための道のり

Cyan
December 12, 2022

 OpenAPIによるスキーマ駆動開発を実現するための道のり

Kotlin Fest Reject Conference 2022 発表資料

Cyan

December 12, 2022
Tweet

More Decks by Cyan

Other Decks in Programming

Transcript

  1. Copyrights(c) Henry, Inc. All rights reserved.
    OpenAPIによる
    スキーマ駆動開
    発を実現するため
    の道のり

    @shenyu_cyan

    View Slide

  2. Copyrights(c) Henry, Inc. All rights reserved.
    自己紹介
    略歴


    音声認識の会社にて自然言語処理の R&Dエンジニアとして務めた
    後、株式会社ビズリーチへ転職し、複数のサービス開発のリードやプ
    ロジェクト管理、エンジニア採用などを経験。 2021年からヘンリーに
    参画。

    StrengthsFinder


    1. 学習欲

    2. 個別化

    3. 包含

    4. 最上志向

    5. アレンジ


    View Slide

  3. Copyrights(c) Henry, Inc. All rights reserved.
    アジェンダ
    • WHY なぜOpenAPIによるスキーマ駆動開発を使うべきと判断し
    たのか

    • Contract-first vs. Code-first

    • OpenAPI vs. GraphQL vs. gRPC

    • WHAT サーバーサイドKotlinでスキーマ駆動開発を実現するため
    の守破離


    View Slide

  4. Copyrights(c) Henry, Inc. All rights reserved.
    Contract-first vs. Code-first
    予約システム

    名簿システム

    検査報告システム

    Henry

    Integration API


    View Slide

  5. Copyrights(c) Henry, Inc. All rights reserved.
    Contract-first vs. Code-first
    OpenAPI Specification (OAS) Kotlin

    View Slide

  6. Copyrights(c) Henry, Inc. All rights reserved.
    Contract-first vs. Code-first
    OpenAPI Specification (OAS)
    Kotlin e.g. SpringFox / SpringDoc

    View Slide

  7. Copyrights(c) Henry, Inc. All rights reserved.
    Contract-first vs. Code-first
    予約システム

    名簿システム

    検査報告システム

    Henry

    Integration API

    外部サービスベンダー様と協業する際のワークフローを
    考慮
    ● 要求の認識合わせ
    ● APIの仕様のフィックス
    ● 各自が実装
    ● 結合テスト
    ● リリース

    View Slide

  8. Copyrights(c) Henry, Inc. All rights reserved.
    Contract-first vs. Code-first

    View Slide

  9. Copyrights(c) Henry, Inc. All rights reserved.
    OpenAPI vs. GraphQL vs. gRPC
    ● 自動生成ツールチェーン周りのエコシステムが充実し、カスタマイズをそれほど多く行わなくてもいい。

    ● 外部サービスと連携する部分のプロトコルなので、社内で蓄積されているナレッジはあくまで考慮要素の一つで、世
    の中のノウハウの充実さが非常に重要である。

    View Slide

  10. Copyrights(c) Henry, Inc. All rights reserved.
    
 gRPC
 GraphQL
 OpenAPI

    自動生成
 First Party

    GraphQL Code
    Generator

    OpenAPI Generator

    Swagger Codegen

    利用ノウハウ

    社内にはあるが、世の中で
    はまだそれ程多くない

    
 

    OpenAPI vs. GraphQL vs. gRPC

    View Slide

  11. Copyrights(c) Henry, Inc. All rights reserved.
    スキーマ駆動開発を実現する為に
    守
 破
 離


    View Slide

  12. Copyrights(c) Henry, Inc. All rights reserved.
    スキーマ駆動開発を実現するための守
    ● OpenAPI Generatorプロジェクトの全体像を把握

    ● Gradleプロジェクトで使うための設定方法

    守


    View Slide

  13. Copyrights(c) Henry, Inc. All rights reserved.
    OpenAPI Generatorプロジェクト
    の全体像を把握
    2018年、Swagger Codegen バージョン2.4からフォークされた
    コミュニティ駆動のOSSプロジェクト


    その歴史については @NAKANO_Akihitoさんのスライド「平静を
    保ち、コードを生成せよ 〜 OpenAPI Generator誕生の背景と
    軌跡 〜」をご参照ください。


    View Slide

  14. Copyrights(c) Henry, Inc. All rights reserved.
    OpenAPI Generatorプロジェクト
    の全体像を把握
    openapi-generator

    実行可能なJARプログラム OpenAPI Generatorのインタフェース
    Gradle Plugin
    メインの実装

    View Slide

  15. Copyrights(c) Henry, Inc. All rights reserved.
    OpenAPITools

    Bazelのプラグイン
    CLIのNode ラッパー
    sbtのプラグイン
    OpenAPI Generatorプロジェクト
    の全体像を把握

    View Slide

  16. Copyrights(c) Henry, Inc. All rights reserved.
    openapi-generator-core
    openapi-generator
    openapi-generator-cli
    openapi-generator-
    gradle-plugin
    sbt-openapi-generator
    openapi-generator-cli
    (Node Wrapper)
    OpenAPI Generatorプロジェクト
    の全体像を把握
    Henryのサーバーサイドアプリは
    Kotlin+Gradleに統一している為、
    こちらだけ意識すれば OK

    View Slide

  17. Copyrights(c) Henry, Inc. All rights reserved.
    Gradleプロジェクトで使うための
    設定方法
    openapiプロジェクトを利用した実装モジュール
    Generatorによって生成されたモジュール
    OpenAPIの定義ファイル
    マルチモジュール構造のプロジェクト
    ワークフロー
    1. spec.ymlにてRestful APIの定義を行う
    2. OpenAPI Generator Gradle Pluginを利
    用して、Gradleタスクを実行することでエ
    ンドポイントとDTOのKotlinコードを自動作
    成 (openapiモジュール)
    3. 実装(app)モジュールにて自動生成され
    たエンドポイントのインタフェースを継承
    し、DTOを活用する

    View Slide

  18. Copyrights(c) Henry, Inc. All rights reserved.
    Gradleプロジェクトで使うための
    設定方法
    include("app")
    include("openapi")

    View Slide

  19. Copyrights(c) Henry, Inc. All rights reserved.
    Gradleプロジェクトで使うための
    設定方法
    dependencies {

    implementation(project(":openapi"))
    }

    View Slide

  20. Copyrights(c) Henry, Inc. All rights reserved.
    Gradleプロジェクトで使うための
    設定方法

    View Slide

  21. Copyrights(c) Henry, Inc. All rights reserved.
    Gradleプロジェクトで使うための
    設定方法
    *設定例として抜粋
    Gradleプラグインの設定

    ジェネレーター設定

    テンプレートの設定


    View Slide

  22. Copyrights(c) Henry, Inc. All rights reserved.
    スキーマ駆動開発を実現するための破
    ● 自作テンプレートの活用

    ● 複数の定義ファイルへの対応

    破


    View Slide

  23. Copyrights(c) Henry, Inc. All rights reserved.
    自作テンプレートの活用
    協力会社へ提供するAPIとはいえ、外部向けのAPIサーバーなので、
    入力に対するバリデーションが必要。
    ソースコード(modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor)内で確認
    したら確かにuseBeanValidationの記述がなかった(非サポートだった)

    View Slide

  24. Copyrights(c) Henry, Inc. All rights reserved.
    自作テンプレートの活用
    User-defined Templatesを利用すれば、既存のテンプレートを簡単に
    オーバーライドできる。
    • build.gradle.ktsのopenApiGenerate設定に自作テンプレの場所を
    指定
    templateDir.set("$rootDir/openapi/templates")
    • テンプレを作成し、オーバーライドしたいファイルのテンプレ名と同
    じ名前のファイルとして上記のフォルダに格納する
    AppMain.kt→AppMain.kt.mustache
    build.gradle→build.gradle.mustache
    弊社では、BeanValidatation以外に、ロギングやデータマスキングのた
    めに自作テンプレートを活用している。
    OpenAPI Generator

    Gradle Plugin

    KotlinServerCodegen

    (org.openapitools.codegen.languag
    es.KotlinServerCodegen)

    Default Templates

    (modules/openapi-generator/src/m
    ain/resources/kotlin-server/libraries
    /*.mustache)

    Kotlin Code

    (openapi/*.kt)


    View Slide

  25. Copyrights(c) Henry, Inc. All rights reserved.
    複数の定義ファイルへの対応
    対応するAPIが増えることによって、全てのAPI定義を一つのファイル
    にまとめることは書きづらさ、メンテナンスしにくさに直結してしまう。
    spec.yml Kotlinコード
    spec.x.yml
    spec.y.yml
    spec.z.yml
    spec._base.yml

    View Slide

  26. Copyrights(c) Henry, Inc. All rights reserved.
    複数の定義ファイルへの対応
    • @alexlafroscia/yaml-merge(NPMライブラリ)を使って定義ファイルのマージを行う
    • Frontend Gradle Plugin (org.siouan.frontend-jdk11)を使ってGradleタスクとして定義
    • GradleタスクopenApiGenerateの依存関係(dependsOn)に定義ファイルマージのGradleタスク
    を追加
    spec.yml Kotlinコード
    spec.x.yml
    spec.y.yml
    spec.z.yml
    spec._base.yml

    View Slide

  27. Copyrights(c) Henry, Inc. All rights reserved.
    スキーマ駆動開発を実現するための離
    Generator自作の道へ

    離


    View Slide

  28. Copyrights(c) Henry, Inc. All rights reserved.
    Generator自作の道へ
    Gradleプロジェクトの完全Kotlin DSL化やフレームワークをKtor2へ
    バージョンアップするために、自作テンプレでバッチを当て続けること
    の限界を感じ始めている。
    KotlinServerCodegen
    BeanValidationFeatures
    AbstractKotlinCodegen
    DefaultCodegen
    CodegenConfig
    KotlinKtor2CodegenKt
    完全自作が大変なので、なるべく
    既存の基底クラスの恩恵を受け
    つつカスタマイズしたい
    (Java Interopが本領発揮)

    View Slide

  29. Copyrights(c) Henry, Inc. All rights reserved.
    まとめ
    • PRO: 仕様を簡単に作成でき、それを持って協力会社と認識合わ
    せ・同時開発するワークフローを実現できている。
    • PRO: カスタマイズ性が高く、既存機能に満足できない場合でも自
    作で問題解決を実現できる。
    • CON: 幅広い言語と機能へ対応しているため、逆にKotlin関係のメ
    ンテナンスが遅れたりする。
    • CON: ドキュメントを読んでもやり方がわからないケースが少なくな
    いため、ソースコードまで調べなければいけない場合がある。

    View Slide

  30. Copyrights(c) Henry, Inc. All rights reserved.
    医療DX
    難しい課題の解決
    社会貢献
    これらのキーワードが気になる方

    一度カジュアルにお話ししましょう
    We are Hiring !




    https://jobs.henry-app.jp/


    View Slide