Slide 1

Slide 1 text

Copyright © NTT Communications Corporation. All rights reserved. NTT Communications 技術開発部 奥井 寛樹 
 React HooksとGraphQLで 社内レガシーサービス巻き取ってみたら ものすごくはかどった話 NTT Tech Conference #4 


Slide 2

Slide 2 text

Copyright © NTT Communications Corporation. All rights reserved. 奥井 寛樹 - NTTコミュニケーションズ株式会社 技術開発部 伝送NW担当のソフトウェアエンジニア(2016/7〜) - WDM〜L2あたりのSDNコントローラ・オーケストレータ開発 - NW装置のモデルベース制御(Cisco NSO、ODL、ONOS) 最近かなりフロントエンド寄り - React信者です 今日もフロントエンド + BFF の話 自己紹介

Slide 3

Slide 3 text

Copyright © NTT Communications Corporation. All rights reserved. どんな案件?

Slide 4

Slide 4 text

Copyright © NTT Communications Corporation. All rights reserved. 例の構成管理システムが、ついに機能提供やめるんだってさ! とはいえ、まだ社内で広く利用されてて畳むわけにはいかないし、 自分たちで巻取るしかないね。 サービス停止まであと3ヶ月しかないんだけど、 巻取りの開発お願いできるかな? 突然ですが茶番です(ほぼ実話)

Slide 5

Slide 5 text

Copyright © NTT Communications Corporation. All rights reserved. なんか当時はすごい金かけて外注して作ったらしいんだけど、 お金ないし、メンバーも君入れて5人しかいないんだけど 内製でアジャイルでやれば、すぐ開発できちゃうんでしょ? DBスキーマの解析はある程度終わってるらしいし、 なんとかなるよね! 頑張って! 突然ですが茶番です(ほぼ実話)

Slide 6

Slide 6 text

Copyright © NTT Communications Corporation. All rights reserved. うーん、backendは確かに進んでるけど、 frontendが皆無に近いぞ。。。 しかも過去案件の構成をそのまま採用してて django + 一部だけAngularJS の構成。 令和のご時世にこれやるの辛い。。。 突然ですが茶番です(ほぼ実話)

Slide 7

Slide 7 text

Copyright © NTT Communications Corporation. All rights reserved. うーん、backendは確かに進んでるけど、 frontendが皆無に近いぞ。。。 しかも過去案件の構成をそのまま採用してて django + 一部だけAngularJS の構成。 令和のご時世にこれやるの辛い。。。 Reactにしたいし、Hooks出たから使いたい。。。 でも中途半端に入れても工数増えるだけだし、かといって 全Replaceするとこれまでの実装が無駄になる。。。 突然ですが茶番です(ほぼ実話)

Slide 8

Slide 8 text

Copyright © NTT Communications Corporation. All rights reserved. 。。。まあいいや! 新しいもの触りたい!! 自分が楽しく仕事できることが一番大事!!! (正しいけどあかんやつ) 品質と納期さえ守れれば何でもいいよね! 体制?維持管? きっとなんとかなる!! がんがん新しいもの入れて作ろー(^O^)/ (2週間PoCやって、だめだったら諦めよう) 突然ですが茶番です(ほぼ実話)

Slide 9

Slide 9 text

Copyright © NTT Communications Corporation. All rights reserved. これが大失敗でした    大成功

Slide 10

Slide 10 text

Copyright © NTT Communications Corporation. All rights reserved. ベロシティグラフ(実データ) MVP実装 コーチング 認証系 他メンバー主体での開発 (ほぼreviewのみの参加) 追い込み MVPが評価され 方式承認もらう スプリント1
 スプリント2
 スプリント3
 スプリント4
 スプリント5
 スプリント6
 2019/9
 2019/12
 2019/10
 2019/11


Slide 11

Slide 11 text

Copyright © NTT Communications Corporation. All rights reserved. ベロシティグラフ(実データ) スプリント1
 スプリント2
 スプリント3
 スプリント4
 スプリント5
 スプリント6
 MVP実装 コーチング 認証系 他メンバー主体での開発 (ほぼreviewのみの参加) 追い込み 2019/9
 2019/12
 2019/10
 2019/11
 MVPが評価され 方式承認もらう

Slide 12

Slide 12 text

Copyright © NTT Communications Corporation. All rights reserved. うまくいった理由 frameworkによる抽象化がうまく、ユースケースにfocusした開発ができた - MVP prototypingが爆速でできた - メンバーへのコーチングが容易で、立ち上がりが早かった GraphQLエコシステムが充実していて、コード品質維持やテスト実装で楽できた

Slide 13

Slide 13 text

Copyright © NTT Communications Corporation. All rights reserved. 2019年に流行ったWeb系のHotな技術 React Hooks? GraphQL? 引用: https://www.thoughtworks.com/radar/languages-and-frameworks?blipid=986

Slide 14

Slide 14 text

Copyright © NTT Communications Corporation. All rights reserved. 2019年に流行ったWeb系のHotな技術 React Hooksは、これまでのReactに比べて格段に良くなった GraphQLは、今後のアプリ開発を大きく変えると言われている - frontendの開発がすごく楽になる - その一方で、backend側の開発が難しく複雑になるとも - it’s worth assessing, but it’s not a silver bullet GraphQLのbackendに踏み込まないでfrontendの恩恵だけ受ければ、 React Hooks + GraphQLって Silver bullet なのでは? という話 (アプリ高速開発に関しては) React Hooks? GraphQL?

Slide 15

Slide 15 text

Copyright © NTT Communications Corporation. All rights reserved. 構成

Slide 16

Slide 16 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 django Forms Template - MVP prototypingはdjangoだけで行こう - 社内ツールだし、できれば JSは使わずシンプルに。。 - 可能なら、本番までこれでいきたい

Slide 17

Slide 17 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 django Vanilla jQuery Forms Template - 要件満たせないので、JS入れるしかないか。。 Form POST

Slide 18

Slide 18 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 django Vanilla jQuery REST API Forms Template - JS側にうまくdata連携できないので、AJAX入れねば Form POST REST

Slide 19

Slide 19 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 django Vanilla jQuery REST API Angular React Vue Forms Template - state管理が複雑になってきたので frontend framework入れたい。。。 Form POST REST REST

Slide 20

Slide 20 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 django Vanilla jQuery REST API Angular React Vue Forms Template - あれ、このDOMって誰が管理しているやつだっけ - FormとRESTで同じ機能 2重開発してる。。。 Form POST REST REST

Slide 21

Slide 21 text

Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成 今回の構成 django Vanilla jQuery REST API Angular React Vue Forms Template django Graphene Django React Hooks Apollo Form POST REST REST GraphQL

Slide 22

Slide 22 text

Copyright © NTT Communications Corporation. All rights reserved. React Functional ComponentがStateを扱えるようになったもの - stateをframework側で管理し、state更新の都度 renderingのためにfunc call - React 16.8で待望のリリース 従来のClass Componentより簡単に書ける “だけじゃない” - React lifecycle eventを意識しなくて良くなった - unstableなevent callがなくなった => 余計なrenderingがなくなり性能向上 & state管理が楽に hookが使いやすい - useState, useEffect, useContext... Context APIの使い勝手が向上 - Flux(Redux)によるstate管理を代替でき、データフローがシンプル化 React Hooksとは

Slide 23

Slide 23 text

Copyright © NTT Communications Corporation. All rights reserved. ポストRESTと言われている 新しいAPI protocol - 2015年にfacebookがrelease、徐々に国内でも利用例が増えてきた query responseを、serverではなくclientが決められる POST RPCに原点回帰しつつ、利便性と柔軟性を高めたAPI - endpointは POST /graphql 一つだけ(欲しいresourceはqueryの中で指定) - variable injectionを標準具備。template engine不要 - スキーマファースト - graphql開発環境がついてくるので、APIテストが楽 GraphQLとは REST GraphQL resource URL指定したものだけ取得 queryに含まれるもの全て attribute server sideで定義した全情報 queryに含まれるものだけ

Slide 24

Slide 24 text

Copyright © NTT Communications Corporation. All rights reserved. PythonのGraphQL framework ORM model定義に基づいてGraphQL APIを自動生成してくれる - Django、Flask、SQLAlchemy が利用可能 低コストにGraphQL backend APIを構築できる - REST API構成するより断然楽 - model classをbindするだけで利用可(custom propertyも、型を定義するだけで利用できる) - relationはグラフエッジとして扱い、勝手にnestして取得してくれる - paginationなどの機能も標準具備(※) Python ORM の既存システムを簡単に拡張できる Grapheneとは ※ ただし、Relay specificationを使用する場合に限る

Slide 25

Slide 25 text

Copyright © NTT Communications Corporation. All rights reserved. 一番人気があり、機能も充実しているGraphQL library GraphQL backend libraryとfrontend clientを提供 - 力を入れているのはReactのみっぽい、AngularやVueもサポートとあるが薄そう React Hooksにnative対応、公式のcustom hookがある - useQuery、useMutation、useSubscription - Component志向の開発がやりやすい cache機能が標準具備 - 複雑な要件でなければ、十分な機能を具備(運用系のアプリなら正直これで十分) Apolloとは

Slide 26

Slide 26 text

Copyright © NTT Communications Corporation. All rights reserved. 結局、何が良かったの?

Slide 27

Slide 27 text

Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django や Rails 単独でMVP実装するのと同じ感覚で SPA + BFFが書ける - GraphQL APIを作るのが 簡単 - Clientからのbackend callが 簡単&柔軟 - React Hooks で Componentを 簡単に実装 漸近的型付け(Gradual Typing) - 型の自動生成 - testで楽できる コンポーネント指向で構成を簡単に

Slide 28

Slide 28 text

Copyright © NTT Communications Corporation. All rights reserved. GraphQL APIを作るのが簡単 django modelをGrapheneでwrapする実装の例 通常なら スキーマ定義 と resolver と datasourceが必要 => 全て隠蔽 modelの登録 登録したmodelを GraphQL queryにbind user ➔ ID指定のget all_users ➔ get all (paginationやfilter具備)

Slide 29

Slide 29 text

Copyright © NTT Communications Corporation. All rights reserved. GraphiQL で検証 & doc確認できる GraphQL APIを作るのが簡単 client側で定義した query 
 & custom func
 request query request variable response custom functionの引数
 Schema document Document見ながら検証でき る
 このcursorを引数にcallすると、次のpageが 取得できる


Slide 30

Slide 30 text

Copyright © NTT Communications Corporation. All rights reserved. Apolloを使ってgraphQL callをReact Componentにbindする実装例 Client側のbackend callが 簡単 & 柔軟 GraphQL query
 bind対象のReact Component 
 
 1. useQuery hookを使うと 
 取得対象のdataだけでなくloading stateやerror stateが取れる 
 ➔ それらを使ってcomponent state 管理ができる
 
 2. backend modelやcallまで 
 含めてcomponent内に凝集可 


Slide 31

Slide 31 text

Copyright © NTT Communications Corporation. All rights reserved. 認証機能の実装例 React HooksでComponentを簡単に実装 316 sagas/auth-saga.js 176 redux/auth-reducer.js 41 types/auth.js 145 containers/auth.js 53 components/auth/login.js 731 total 174 contexts/AuthContext.js 116 containers/Login.js 290 total React Component + redux + redux-saga 
 React Hooks + Context


Slide 32

Slide 32 text

Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django や Rails 単独でMVP実装するのと同じ感覚で SPA + BFFが書ける - GraphQL APIを作るのが 簡単 - Clientからのbackend callが 簡単&柔軟 - React Hooks で Componentを 簡単に実装 漸近的型付け(Gradual Typing) - 型の自動生成 - testで楽できる コンポーネント指向で構成を簡単に

Slide 33

Slide 33 text

Copyright © NTT Communications Corporation. All rights reserved. 漸近的型付け(Gradual Typing) 漸近的型付け:動的型付け言語に後付で型をつけるもの - Javascript: Typescirpt, Flow、Python: typing/mypy、Dart など - ランタイム生成のためではなく、ドキュメンテーションのため 検査可能なドキュメントとしての価値 - 違反型のAssertionを書くことなく 型の制約を与えられる - IDEや検査ツールを使って静的型検査 ➔ 動かす前に型違反を検出できる 開発者のためのドキュメントとしての価値 - 型情報があることで可読性が向上する(JsDoc、PyDocを薄くできる) - CIで型検査できることで、更新忘れを防止 - Reviewが楽 型が必須ではないので、最悪skipできる & any に逃げられる

Slide 34

Slide 34 text

Copyright © NTT Communications Corporation. All rights reserved. でも型を書くのはめんどくさい backend logic実装 frontend view実装 backend frontend graphQL query実装

Slide 35

Slide 35 text

Copyright © NTT Communications Corporation. All rights reserved. でも型を書くのはめんどくさい model flowtype d.ts backend logic実装 frontend view実装 backend frontend graphQL query実装

Slide 36

Slide 36 text

Copyright © NTT Communications Corporation. All rights reserved. でも型を書くのはめんどくさい model flowtype d.ts backend logic実装 graphQL query実装 frontend view実装 API Doc graphQL query API Docの記述 (schema.json)
 API Docに基づく
 query validation
 queryに基づく
 型作成
 backend frontend

Slide 37

Slide 37 text

Copyright © NTT Communications Corporation. All rights reserved. 型自動生成で 快適な Gradual Typing を実現 model graphQL schema flowtype d.ts backend logic実装 graphQL query実装 JS GraphQL manage.py graphql_schema apollo client:codegen frontend view実装 API Doc backend frontend graphQL query

Slide 38

Slide 38 text

Copyright © NTT Communications Corporation. All rights reserved. testで楽をする(ただし品質は下げない) frontendのunit test: 内部stateがないFunctional Component は unit testしなくてすむ - 型安全なコーディングをしているので、renderingがfailすることはない - E2E testでcrashしないことが確認できればよい (参考)テスト内訳 サイズ テスト種別 補足 small frontend unit test frontend snapshot backend unit test skip skip ✓ 上記より割愛、coreのみ実施 社内ツール開発で頑張るメリットが薄いので、割愛 model testは恩恵が大きいのでちゃんとやる medium E2E test (auto) ✓ cypress利用 large QA: E2E test (manual) ✓

Slide 39

Slide 39 text

Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django や Rails 単独でMVP実装するのと同じ感覚で SPA + BFFが書ける - GraphQL APIを作るのが 簡単 - Clientからのbackend callが 簡単&柔軟 - React Hooks で Componentを 簡単に実装 漸近的型付け(Gradual Typing) - 型の自動生成 - testで楽できる コンポーネント指向で構成を簡単に

Slide 40

Slide 40 text

Copyright © NTT Communications Corporation. All rights reserved. コンポーネント指向で構成を簡単に React Hooks & Context と Apollo による 適度な抽象化のおかげで state管理の複雑さからかなり解放される(実装量が削減できる) 関心をコンポーネントに凝集(分離ではなく) - model(backend call) を分離しない、view(Component)とセットで凝集する (reduxで action/reducer/middleware と分離して複雑化したことへの反省) - 複雑な状態遷移ができないが、小〜中規模程度の開発ならむしろこの方が楽 無理に汎化しすぎない - 汎化するものは小さく、汎用度高く - 不確実性とうまく付き合う(DRYを頑張りすぎない)

Slide 41

Slide 41 text

Copyright © NTT Communications Corporation. All rights reserved. 課題 Mutationはそんなに楽できない - 型やlocal cache updateの恩恵は受けられる - が、普通にRPC実装するのとそこまで変わらない React Hooksでのmutable objectのstate管理は結構はまりやすい - Controlled FormとInner Functional Componentの組み合わせ - stateを持つがReactで実装されていない外部library - ちゃんと作り込めばcustom hooksに隠蔽できる Apolloはかなり完成度が高いが、少し課題も見える - query functionをglobal uniqueにしないと型生成でコケる (本当はquery uniqueでよい) - 同じmodelを参照していても、graphql nodeが異なるとcache updateされない

Slide 42

Slide 42 text

Copyright © NTT Communications Corporation. All rights reserved. (私見)社内レガシーは 内製しやすい & 新技術導入しやすい 性能要件がゆるめ - レスポンスに寛容(ひどいレスポンスのサービスが社内に結構ある) - 利用者がそもそも少ないので、そんなに高負荷にならない SLAが低め - 多少壊れてもすぐに復旧できれば大丈夫 - (委託先にエスカレして改修して工事指示して・・・の工程よりは大概早く対応できる) WorkAroundを許容してもらいやすい - ユーザとコミュニケーションが取りやすいことのメリット ただし、巻取り元serviceの仕様は細かく作り込まれていて膨大 - 「全てを真に受ける」ことはしないことが大事 - leanな開発、feedback driven developmentがここでも有効

Slide 43

Slide 43 text

Copyright © NTT Communications Corporation. All rights reserved. Takeaways React Hooks & GraphQLは、Rails/django のMVP開発の代替たりうる 漸近的型付けを強力にサポートしてくれる。楽に型安全コーディング 社内レガシーは新技術を試す格好の場(なことが多い)。新しいものを試そう