Slide 1

Slide 1 text

2022-07-20 Backend LT 会 Shumpei IINUMA ( 株式会社令和トラベル) はじめてのGraphQL in Production ~ 得た学びと課題 ~

Slide 2

Slide 2 text

Shumpei IINUMA 令和トラベルでバックエンドエンジニアをしています 新しい旅行を体現するアプリ「NEWT 」と、それを提供 するための旅行管理システムのAPI やインフラの開発 ~ 2015 大学院で自然言語処理を学ぶ 2016 ~ 2017 リクルートでサイト内検索ロジックの開発 2017 ~ 2021 SaaS プロダクトの開発 2022 ~ 令和トラベルにジョイン 主な仕事内容 略歴 @iinm_stderr @iinm

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

前提:システムのコンポーネントとチーム構成 Public schema Private schema Admin NEWT Android Team iOS Team Frontend Team Backend Team API 社内向け ツアー入稿・在庫管理 予約管理 カスタマー向け 海外ツアー予約

Slide 6

Slide 6 text

なぜGraphQL を選び、どう使っているのか?

Slide 7

Slide 7 text

Server - Client 間でのInterface の共有方法として プロダクトの機能開発に集中できるように 手間を掛けずに利用できるエコシステムが 存在して、Android, iOS, Browser, この3 つのプラットフォームに対応してい ること ( 定番のApollo GraphQL) バイナリでやり取りするものはBrowser 向けにProxy が必要 OpenAPI Schema は、私には読むのも書くのも辛かった zenn.dev Backend Technology Selection for Building a digital travel agency Hello! My name is Rodrigo Ramirez; I'm a Full-stack developer, entrepreneur, and Argentinian. I have been living in Tokyo, Japan, since 2014. I'm working as a Backend lead engineer at ReiwaTravel, and together with an amazing team, we are trying to unlo… 当初、弊社エンジニアが考えた内容はこちらのBlog を参照→ 他に選択肢はなかったのか?

Slide 8

Slide 8 text

Code-​ first かSchema-​ first か? 私たちはCode-​ first TypeScript の表現能力 (Generics, Module) を使って重複なく整理された状態にしたかった NEWT 、Admin 向けの2 つのSchema 間で共通す る型も多い class 、function にアノーテーションを付けてい るだけなので、生のSchema を書くよりも速い その他工夫 Code を書く前にラフにSchema を書いてレビュ ーし合う 生成したSchema はGit 管理して、意図しない変 更がないことをレビューし合う

Slide 9

Slide 9 text

Codebase は一つ、Schema は2 つ Public schema Private schema カスタマー/NEWT 向け 社内/Admin 向け ドメイン毎にResolver を整理 共通で使うObject のprivate なField はRe solver を分けることでPrivate Schema だけで見せる

Slide 10

Slide 10 text

実際に使ってみて、どんな課題があったか?

Slide 11

Slide 11 text

一方のClient に過剰適合してしまったInterface Public schema Private schema カスタマー/NEWT 向け 社内/Admin 向け どうするべきだった? 何が起きたか? Admin でしか使わないField をNEWT で参照、カスタ マーに誤った情報を表示してしまった NEWT に必要な情報がRelation を深く辿らないと必 要な情報が取れない 例:tour.flight[0].seatClass 両方のSpec が決まった段階でSchema を見直す 不必要なField はSchema に表出させない わざわざRelation を辿らなくても取りやすいよ うに親に参照用のField を付ける 背景:テストデータを先行して作れるようNEWT のSpec が 決まる前にAdmin のSpec を作るケースがある

Slide 12

Slide 12 text

まさかのOver fetching GraphQL のメリットでよく言われる話 Client が必要なField を指定出来るので、データを受け取り 過ぎて無駄に通信量を増やすOver-​ fetching が起こりにくい 何が起きたか? Over-​ fetching が発生して画面描画が異常に遅くなっていた なぜ起きたか? 取得するField のセットを再利用するためのfragment 詳細取得で使うfragment を一覧取得にも使い回した 結果、レスポンスボディが巨大になっていた どうするべきだったのか? fragment からfragment を参照できたりするので 、最終的なQuery の形が想像しづらい そもそも巨大なクエリを発行できないようにSe rver で制限 Client 開発者はレスポンスサイズを気にしてみ てください

Slide 13

Slide 13 text

Schema は誰のもの? 課題感・モヤモヤ (全てではないが)基本はBackend Team だけでSchema を決めている 全員がFull-​ stack ではないのでどこまでClient-​ first にできるかはまちまち インシデントや負債になる前に、Client 実装者からの提案・議論がもっとあっても良いのではないか? どうするべき? 組織の性格にも依るが、Client - Server 両方の開発者がオーナーシップを持って作っていきたい 以前、Client 主導でSchema を決める組織もあり、Backend&Frontend のモノレポで両チームがイイ感 じにコラボレーションしていた(Web のみの場合はこれで問題なかったが、NEWT はネイティブもあ り、リリースサイクルが異なるため混ぜにくい) いい感じにやっているよ、の例があればぜひ教えてください!

Slide 14

Slide 14 text

今後、どんな課題を解決していくのか?

Slide 15

Slide 15 text

No content