Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Hiroki Okui
January 31, 2020

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

Hiroki Okui

January 31, 2020
Tweet

More Decks by Hiroki Okui

Other Decks in Programming

Transcript

  1. Copyright © NTT Communications Corporation. All rights reserved.
    NTT Communications 技術開発部 奥井 寛樹 

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


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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


    View Slide

  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が評価され
    方式承認もらう

    View Slide

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

    View Slide

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

    View Slide

  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?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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とは

    View Slide

  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に含まれるものだけ

    View Slide

  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を使用する場合に限る

    View Slide

  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とは

    View Slide

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

    View Slide

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

    View Slide

  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具備)

    View Slide

  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が
    取得できる


    View Slide

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


    View Slide

  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


    View Slide

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

    View Slide

  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 に逃げられる

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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) ✓

    View Slide

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

    View Slide

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

    View Slide

  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されない

    View Slide

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

    View Slide

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

    View Slide