React HooksとGraphQLで社内レガシーサービスを巻き取ってみたらものすごくはかどった話

9ae881da1ae8ed4fd6cdc0f47eae46f6?s=47 hrk091
January 31, 2020

React HooksとGraphQLで社内レガシーサービスを巻き取ってみたらものすごくはかどった話

9ae881da1ae8ed4fd6cdc0f47eae46f6?s=128

hrk091

January 31, 2020
Tweet

Transcript

  1. Copyright © NTT Communications Corporation. All rights reserved. NTT Communications

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

  2. Copyright © NTT Communications Corporation. All rights reserved. 奥井 寛樹

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

  4. Copyright © NTT Communications Corporation. All rights reserved. 例の構成管理システムが、ついに機能提供やめるんだってさ! とはいえ、まだ社内で広く利用されてて畳むわけにはいかないし、

    自分たちで巻取るしかないね。 サービス停止まであと3ヶ月しかないんだけど、 巻取りの開発お願いできるかな? 突然ですが茶番です(ほぼ実話)
  5. Copyright © NTT Communications Corporation. All rights reserved. なんか当時はすごい金かけて外注して作ったらしいんだけど、 お金ないし、メンバーも君入れて5人しかいないんだけど

    内製でアジャイルでやれば、すぐ開発できちゃうんでしょ? DBスキーマの解析はある程度終わってるらしいし、 なんとかなるよね! 頑張って! 突然ですが茶番です(ほぼ実話)
  6. Copyright © NTT Communications Corporation. All rights reserved. うーん、backendは確かに進んでるけど、 frontendが皆無に近いぞ。。。

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

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

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

  10. Copyright © NTT Communications Corporation. All rights reserved. ベロシティグラフ(実データ) MVP実装

    コーチング 認証系 他メンバー主体での開発 (ほぼreviewのみの参加) 追い込み MVPが評価され 方式承認もらう スプリント1
 スプリント2
 スプリント3
 スプリント4
 スプリント5
 スプリント6
 2019/9
 2019/12
 2019/10
 2019/11

  11. Copyright © NTT Communications Corporation. All rights reserved. ベロシティグラフ(実データ) スプリント1


    スプリント2
 スプリント3
 スプリント4
 スプリント5
 スプリント6
 MVP実装 コーチング 認証系 他メンバー主体での開発 (ほぼreviewのみの参加) 追い込み 2019/9
 2019/12
 2019/10
 2019/11
 MVPが評価され 方式承認もらう
  12. Copyright © NTT Communications Corporation. All rights reserved. うまくいった理由 frameworkによる抽象化がうまく、ユースケースにfocusした開発ができた

    - MVP prototypingが爆速でできた - メンバーへのコーチングが容易で、立ち上がりが早かった GraphQLエコシステムが充実していて、コード品質維持やテスト実装で楽できた
  13. Copyright © NTT Communications Corporation. All rights reserved. 2019年に流行ったWeb系のHotな技術 React

    Hooks? GraphQL? 引用: https://www.thoughtworks.com/radar/languages-and-frameworks?blipid=986
  14. 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?
  15. Copyright © NTT Communications Corporation. All rights reserved. 構成

  16. Copyright © NTT Communications Corporation. All rights reserved. 構成 ありがちな構成

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

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

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

    django Vanilla jQuery REST API Angular React Vue Forms Template - state管理が複雑になってきたので frontend framework入れたい。。。 Form POST REST REST
  20. 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
  21. 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
  22. 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とは
  23. 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に含まれるものだけ
  24. 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を使用する場合に限る
  25. 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とは
  26. Copyright © NTT Communications Corporation. All rights reserved. 結局、何が良かったの?

  27. Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django

    や Rails 単独でMVP実装するのと同じ感覚で SPA + BFFが書ける - GraphQL APIを作るのが 簡単 - Clientからのbackend callが 簡単&柔軟 - React Hooks で Componentを 簡単に実装 漸近的型付け(Gradual Typing) - 型の自動生成 - testで楽できる コンポーネント指向で構成を簡単に
  28. 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具備)
  29. 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が 取得できる

  30. 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内に凝集可 

  31. 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

  32. Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django

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

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

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

    flowtype d.ts backend logic実装 frontend view実装 backend frontend graphQL query実装
  36. 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
  37. 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
  38. 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) ✓
  39. Copyright © NTT Communications Corporation. All rights reserved. 何が良かったのか? django

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

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

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

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