Slide 1

Slide 1 text

iOSライブラリをセルフサービスで⽣成する仕組み Sep 11th, 2022 Yusuke Ohashi Architect & SRE Group/Mobile Core Team Rakuten Group, Inc.

Slide 2

Slide 2 text

2 ⾃⼰紹介 Yusuke Ohashi Application Architect@Rakuten Group, Inc. LT at iOSDC 2016(初のiOSDC) in 練⾺ https://github.com/junkpiano https://yusuke.cloud

Slide 3

Slide 3 text

3 What Architect team is doing Standardization Productivity Innovation Cross-Platform, Cross-Functional team - ソリューションの提供、標準化 - 技術調査、選定 - 開発者の⽣産性向上

Slide 4

Slide 4 text

4 セルフサービスとは

Slide 5

Slide 5 text

5 セルフサービスとは

Slide 6

Slide 6 text

6 セルフサービスとは アプリ、APIを 指定 ユーザーへ デリバリー APIクライアン トの⽣成

Slide 7

Slide 7 text

7 Agenda 〜セルフサービスへの道のり〜 背景〜OASの導⼊〜 ⾃動化の仕組みの構築 〜サーバーサイドの整備〜 ⾃動化の仕組みの構築 〜ツール&UIの開発〜 Swiftコード⽣成の実例 まとめ&告知

Slide 8

Slide 8 text

8 OASとは - https://www.openapis.org/ - Open API Specificationの略 - APIのデザインドキュメンテーション - Method - Headers - Parameters - Response - Etc. - YAML, JSONで記述 - Swaggerとの違い - ここではOASの実装やツールの総称としてSwaggerを使う - https://swagger.io/blog/api-strategy/difference-between-swagger-and-openapi/

Slide 9

Slide 9 text

9 OASとは

Slide 10

Slide 10 text

10 OASとは Swagger UI https://petstore.swagger.io

Slide 11

Slide 11 text

11 OASとは Swagger Codegen – Client SDK/Server Stub Generator https://swagger.io/tools/swagger-codegen/ https://github.com/swagger-api/swagger-codegen

Slide 12

Slide 12 text

12 背景〜OASの導⼊〜

Slide 13

Slide 13 text

13 APIの乱⽴によるクライアントの複雑化

Slide 14

Slide 14 text

14 背景 〜OASの導⼊〜 API API API API API API * 2022/08/01 時点

Slide 15

Slide 15 text

15 背景 〜OASの導⼊〜 - クライアントにロジックが集中 - スパゲッティコード化しやすい - iOS/Androidで機能の差分が出る

Slide 16

Slide 16 text

16 モバイルアプリの機能に合わせたAPIへ

Slide 17

Slide 17 text

17 背景 〜OASの導⼊〜 BFF API Gateway API Gateway API API API API API API How to design? * 2022/08/01 時点

Slide 18

Slide 18 text

18 BFFのデザインにOASを導⼊

Slide 19

Slide 19 text

19 背景〜OASの導⼊〜 デザイン ->実装 ⾃動化への基盤 開発者の負担減

Slide 20

Slide 20 text

20 ⾃動化の仕組みの構築〜サーバーサイド〜

Slide 21

Slide 21 text

21 OpenAPI Specificationの管理 Jenkins logo by https://jenkins.io/

Slide 22

Slide 22 text

22 OpenAPI Specificationの管理 - API ProviderがGitで管理 - Pull RequestでAPIスペックのレビュー - Mobileのエンジニアも修正に参加

Slide 23

Slide 23 text

23 OpenAPI Specificationの管理 - Open API Specificationのガイドライン - Yamlのvalidationツールの使⽤ - $refをまとめるための、Bundleツールの開発

Slide 24

Slide 24 text

24 ここまでがOASの仕込み

Slide 25

Slide 25 text

25 ⾃動化の仕組みの構築〜UI及びツールの開発〜

Slide 26

Slide 26 text

26 Code Generatorの開発

Slide 27

Slide 27 text

27 ⾃前のCode Generatorの開発 - すでにコード⽣成機能は実装されている - なぜ⾃前のcode generatorが必要なのか︖

Slide 28

Slide 28 text

28 ⾃前のCode Generatorの開発 Official Custom 不要な依存 あり なし テンプレート変更 難 容易 テスト モックライブ ラリなどで可 能 容易

Slide 29

Slide 29 text

29 ⾃前のCode Generatorの開発 ⾃前のcustom code generatorを作る。 Þ作り⽅ → https://github.com/swagger-api/swagger-codegen/tree/3.0.0 - making-your-own- codegen-modules Þこちらで出来たJavaの雛形(maven project)を基にcode generatorを作成 Þテンプレート(mustache)は既存のSwift⽤の実装を参照 ÞJavaの⽅は継承元のクラスから実装を参照 Þドキュメントに乏しい。コードを読みながら書く。

Slide 30

Slide 30 text

30 ⾃前のCode Generatorの開発 〜OASの拡張〜 OASのServerブロックを拡張する例 -> サーバーに名前を追加(Vendor Extension)

Slide 31

Slide 31 text

31 ⾃前のCode Generatorの開発 〜OASの拡張〜 Yaml, テンプレートの変更例

Slide 32

Slide 32 text

32 ⾃前のCode Generatorの開発 〜OASの拡張〜 - 公式のものを使うか、カスタマイズするかは利便性と メンテナンス性のトレードオフ - チームの優先順位に応じて決める - Swiftによる実装もあり(未検証) - https://github.com/yonaskolb/SwagGen

Slide 33

Slide 33 text

33 誰がコードを⽣成するのか︖

Slide 34

Slide 34 text

34 Jenkins Jenkins logo by https://jenkins.io/

Slide 35

Slide 35 text

35 Jenkins as Frontend Jenkins is - ⾔わずと知れたCIエンジン - ⾃由な拡張性 - 豊富なプラグイン - Web Applicationにもなる(APIもある)

Slide 36

Slide 36 text

36 Jenkins as Frontend Jenkins logo by https://jenkins.io/ Slave Node Master Node

Slide 37

Slide 37 text

37 Master Node WebのフロントエンドとしてのJenkins Active Choices https://plugins.jenkins.io/uno-choice/ GroovyスクリプトでDynamicなFormを構築 e.g.) アプリごとに異なるAPI及びバージョンのリストをREST APIで取得

Slide 38

Slide 38 text

38 Master Node

Slide 39

Slide 39 text

39 Master Node https://www.cncf.io/blog/2022/04/06/how-to-render-jenkins-build-parameters-dynamically/

Slide 40

Slide 40 text

40 Slave Node Lint - Push Podspec - Push SDK Git Git - Pull OAS - Code generation

Slide 41

Slide 41 text

41 Delivery Jenkins logo by https://jenkins.io/ Developers

Slide 42

Slide 42 text

42 Swiftコード⽣成の実例

Slide 43

Slide 43 text

43 Swift Package Manager対応

Slide 44

Slide 44 text

44 Package.swift.mustache // swift-tools-version:5.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "{{projectName}}", platforms: [.iOS(.v11), .watchOS(.v4)], products: [ .library(name: "{{projectName}}", targets: ["{{projectName}}"]), ], dependencies: [ ], targets: [ .target(name: "{{projectName}}", dependencies: []), ], swiftLanguageVersions: [.v5] )

Slide 45

Slide 45 text

45 Package.swift // swift-tools-version:5.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: ”SampleLib", platforms: [.iOS(.v11), .watchOS(.v4)], products: [ .library(name: ”SampleLib", targets: [”SampleLib"]), ], dependencies: [ ], targets: [ .target(name: ”SampleLib", dependencies: []), ], swiftLanguageVersions: [.v5] )

Slide 46

Slide 46 text

46 Protocolと実装クラスの⽣成

Slide 47

Slide 47 text

47 Protocolと実装クラスの⽣成 public protocol {{classname}}Protocol { {{#operation}} /** {{#summary}} {{{summary}}} {{/summary}} {{#allParams}} - parameter {{paramName}}: ... {{/allParams}} - parameter completion: completion handler to receive the data and the error objects */ func {{operationId}}({{#allParams}}...{{/allParams}}{{#hasParams}}, {{/hasParams}} completion: @escaping ((_ response: {{{returnType}}}?, _ urlresponse: URLResponse?, _ error: Error?) -> Void)) -> URLSessionTask? {{/operation}} }

Slide 48

Slide 48 text

48 Protocolと実装クラスの⽣成 public protocol SampleListBFFAPIProtocol { /** SampleList API for iOSDC 2022 - parameter authorization: (header) Authorization token - parameter completion: completion handler */ func sampleList(authorization: String, completion: @escaping ((_ response: SampleListResponse?, _ urlresponse: URLResponse?, _ error: Error?) -> Void)) -> URLSessionDataTask? }

Slide 49

Slide 49 text

49 Protocolと実装クラスの⽣成

Slide 50

Slide 50 text

50 Protocolと実装クラスの⽣成 public class SampleListBFFAPI: SampleListBFFAPIProtocol { /** SampleList API for iOSDC 2022 - parameter authorization: (header) Authorization token - parameter completion: completion handler */ @discardableResult public func sampleList(authorization: String, completion: @escaping ((_ response: SampleListResponse?, _ urlresponse: URLResponse?, _ error: Error?) -> Void)) -> URLSessionDataTask? { return ... } }

Slide 51

Slide 51 text

51 Swift Concurrency対応

Slide 52

Slide 52 text

52 Concurrency対応 /** {{#summary}} {{{summary}}} {{/summary}} {{#allParams}} - parameter {{paramName}}: ... {{/allParams}} */ @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) func {{operationId}}({{#allParams}}...{{/allParams}}) async throws -> {{{returnType}}}

Slide 53

Slide 53 text

53 Concurrency対応 /** SampleListAPI for iOSDC 2022 - parameter authorization: (header) Authorization token. */ @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public func sampleListAPI(authorization: String) async throws -> SampleListResponse { let request = ... return try await session.sendRequest(with: request) }

Slide 54

Slide 54 text

54 Tips - 無いファイルを追加するときはcode generatorの実装が不可⽋ - Package.swiftの実装 - Protocolの定義など - 本当に複雑な処理は素直に別にライブラリにする⽅が無難 - ネットワークの実装は単独のライブラリ(共通の実装) - 独⾃の認証処理など - Templateにちょっと何か付け⾜すくらいなら公式のcode generatorで⼗分 - 若⼲の処理の変更 - 関数にコメントを加えるなど

Slide 55

Slide 55 text

55 まとめ

Slide 56

Slide 56 text

56 Takeaways OASベースのコード⽣成の仕組みの整備 Jenkinsを利⽤したセルフサービスのUI構築 ツール内製の強みを⽣かしたテンプレートの拡張 Swiftはテンプレートに馴染みやすい⾔語

Slide 57

Slide 57 text

57

Slide 58

Slide 58 text

No content