Slide 1

Slide 1 text

Gatewayパターンと Schema駆動開発 2019.5.7 @andoshin11

Slide 2

Slide 2 text

Who am I? Shin Ando (Andy) @andoshin11 - Frontend Developer / Architect - Freelance Vue / Nuxt / React / Flutter / Go / Ruby etc... 2

Slide 3

Slide 3 text

話すこと 3 ● アーキテクチャの話 ● Universal Schemaの話 ● TypeScriptの話

Slide 4

Slide 4 text

話さないこと 4 ● Vue.jsの話 ● Nuxt.jsの話 ● ドメイン設計の話 ● 具体的な実装の話 (サンプルは紹介予定)

Slide 5

Slide 5 text

5 本LTの内容は中規模以上 のSPAを想定しています

Slide 6

Slide 6 text

6 「描画」を司るデータ管理の変遷 SPA以前 ● Rails, Symfony等のフルスタックフレームワークで描画も担っていた時代 ● 各Modelから抽出したデータをFatなControllerに集約して描画層へ伝達 ● Dirtyなデータ整形ロジックはバックエンドレイヤーで隠蔽するのが一般的

Slide 7

Slide 7 text

7 「描画」を司るデータ管理の変遷 SPA以前 → SPA黎明期 ● フロントエンドとバックエンドの分離。 HTTPを介した疎なデータ伝達 ● サーバーサイド → バックエンドドメインのREST APIを公開 ● クライアントサイド → APIレスポンスをそのままメモリ上に保存し、描画に利用 描画(Presentation)のたびにクライアントサイドでDirtyなデータ整形処理が必要になる → ページ単位のStoreやPresenter(Getters)が量産される結果に

Slide 8

Slide 8 text

8 「描画」を司るデータ管理の変遷 SPA以前 → SPA黎明期 → SPA成熟期(Now!) ● クライアントデータストアの設計手法が成熟 ● (中規模以上のSPAにおいては)エンドユーザーに対するデータの入出力に特化したクラ イアントドメインの定義が不可欠に ● APIレスポンスをStoreに保存する前のドメイン変換レイヤーが求められるようになる

Slide 9

Slide 9 text

9 (番外編)バックエンドドメインとの乖離 バックエンドのドメイン設計におけるクライテリア ● DBの特性 → Relation Hints, Indexability, etc… ● 言語の特性 → Value ObjectやEntityの扱いやすさ ● FWおよびORMの特性 → Model Layerの扱い、DBとの結合度合い等

Slide 10

Slide 10 text

10 (番外編)バックエンドドメインとの乖離 バックエンドのドメイン設計におけるクライテリア ● DBの特性 → Relation Hints, Indexability, etc… ● 言語の特性 → Value ObjectやEntityの扱いやすさ ● FWおよびORMの特性 → Model Layerの扱い、DBとの結合度合い等 モノリシックなアプリケーションでも上記の制約が発生するのに加えて、マイクロ サービス環境ではさらに個々のドメインが疎になる

Slide 11

Slide 11 text

11 (番外編)バックエンドドメインとの乖離 バックエンドのドメイン設計におけるクライテリア ● DBの特性 → Relation Hints, Indexability, etc… ● 言語の特性 → Value ObjectやEntityの扱いやすさ ● FWおよびORMの特性 → Model Layerの扱い、DBとの結合度合い等 モノリシックなアプリケーションでも上記の制約が発生するのに加えて、マイクロ サービス環境ではさらに個々のドメインが疎になる バックエンドドメインをクライアントドメインに そのまま転写するのは厳しくなる一方

Slide 12

Slide 12 text

12 Translator、作りましょう ※ バックエンドのSchemaを受け取ってクライアントドメイ ンに変換する関数(逆も然り)

Slide 13

Slide 13 text

13 Translatorを挟むのはどこでもOK ● BFF ● API Clientのmiddleware ● API ClientをラップするClient-Side Gateway ● etc...

Slide 14

Slide 14 text

14 バックエンドSchemaはどこから?

Slide 15

Slide 15 text

15 Universal Schema(Swagger)を利用

Slide 16

Slide 16 text

16 YAMLから型定義を自動生成 作った → openapi-ts-gen

Slide 17

Slide 17 text

17 Schemasの型定義

Slide 18

Slide 18 text

18

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

20 現在のワークフロー 1. Swaggerファイルを更新 (バックエンド/フロントエンド共同でメンテ) 2. 型定義をPrivate Registryに公開 3. フロントエンド開発用のStub Serverを更新(シンプルなExpress Server) 4. GatewayのRequest / Response translatorsを更新 → APIの実装ではなくInterfaceについて逐次合意を取ることで高速な開発が可能に → APIの仕様変更はTypeScriptの型エラーとして検知可能。壊れにくい仕組みづくり

Slide 21

Slide 21 text

21 サンプルコード ● https://github.com/andoshin11/sample-petstore-api ● https://github.com/andoshin11/sample-nuxt-pet-store