Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GraphQLでいい感じの検索APIを作りたい
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
estie | エスティ
September 13, 2024
Programming
0
670
GraphQLでいい感じの検索APIを作りたい
2024年9月13日の「テックリードの悩みを解決するGraphQLの話」というイベントで登壇した資料です。
https://estie.connpass.com/event/328999/
estie | エスティ
September 13, 2024
Tweet
Share
More Decks by estie | エスティ
See All by estie | エスティ
dbt×Snowflakeで始めるデータコンペ
estie
0
28
企業価値に繋がるAI事業の創り方
estie
2
2.9k
データの価値を最大化する DaaSのUIデザイン
estie
0
230
エンジニアリングをやめたくないので問い続ける
estie
3
1.5k
第2回 国⼟交通省データコンペ参加者向け勉強会 Snowflake x estie編
estie
1
540
マルチプロダクトを支えるスケーラブルなデータパイプライン設計
estie
1
6.8k
Platformに“ちょうどいい”責務ってどこ? 関心の熱さにあわせて考える、責務分担のプラクティス
estie
2
820
事業価値を作る「攻めるPM、守るPM」
estie
0
220
プレイングにマネジメントに。広がる役割と向き合う中での学び
estie
0
340
Other Decks in Programming
See All in Programming
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
630
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
230
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
5
800
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
660
AIによる開発の民主化を支える コンテキスト管理のこれまでとこれから
mulyu
3
500
Apache Iceberg V3 and migration to V3
tomtanaka
0
170
CSC307 Lecture 06
javiergs
PRO
0
690
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
120
AI時代のキャリアプラン「技術の引力」からの脱出と「問い」へのいざない / tech-gravity
minodriven
21
7.4k
ノイジーネイバー問題を解決する 公平なキューイング
occhi
0
110
Featured
See All Featured
Everyday Curiosity
cassininazir
0
130
A Modern Web Designer's Workflow
chriscoyier
698
190k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.2k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
68
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
67
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.1k
YesSQL, Process and Tooling at Scale
rocio
174
15k
The agentic SEO stack - context over prompts
schlessera
0
650
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
920
Ethics towards AI in product and experience design
skipperchong
2
200
First, design no harm
axbom
PRO
2
1.1k
Transcript
テックリードの悩みを解決するGraphQLの話
© 2023 estie Inc. ソフトウェアエンジニア riano_ GraphQLでいい感じの検索APIを作りたい 1
© 2024 estie, inc. 自己紹介 riano_ • 2022年8月からestieでソフトウェアエンジニア • オフィスの貸主様向けプロダクトの開発
• オフィスの仲介会社様向けプロダクトの開発 • GraphQL化を含むバックエンドの全面リファクタリング • 全社の共通基盤開発を通した開発の加速 • 趣味は競技プログラミング 2
© 2024 estie, inc. 目次 • 実現したい仕様 • 方法案と課題 •
解決方法・まとめ 3
© 2023 estie Inc. 検索APIのジレンマ 4
© 2024 estie, inc. • オフィス物件のデータ • 建物(building)が複数の「募集」(asking)を持っている • その他にも建物を起点に多くのデータ(駅、市区町村、事業者など)が関連づけられている
どんなデータを扱っているか 5 (東京ミッドタウンの画像を用いて架空のデータで作成) 募集区画 階数 募集区画 面積 入居可能時期 備考 3 全 65.00坪 2024/12/05 2 A, B 43.50坪 即入居可
© 2024 estie, inc. • 「募集」を検索する機能を提供している • 条件は「所在地」「竣工年」など建物のものと「賃料」「入居可能日」など募集のものがある • 該当する募集を建物毎に括って表示している
「募集」を検索し、「建物」で表示したい 6 (検索結果画面) 階数 募集区画 面積 入居可能時期 備考 3 全 65.00坪 2024/12/05 2 A, B 43.50坪 即入居可 階数 募集区画 面積 入居可能時期 備考 4 全 65.00坪 2024/11/05 1 A, B 43.50坪 即入居可 サンプルビル1 東京都港区赤坂A-B-C 竣工: 2010年 サンプルビル2 東京都千代田区九段南X-Y-Z 竣工: 2020年
© 2024 estie, inc. • データ構造から、以下のようなスキーマになっている • 検索APIの返り値は [Building!] としたいが、素直にネストした
Asking を取得してはいけない (検索条件によらず、このビルの募集が全てついてきてしまう) GraphQLでどう実装するか? 7 こう書けたら嬉しいが...
© 2024 estie, inc. <理想の要件> • 「建物」と「募集」の条件両方に合致する「募集」を検索したい • それを「建物」ごとにまとめてページネーションして表示したい(APIで全件渡すのは重すぎる) •
通常のデータ取得と同じように、ネストしたクエリで書けると嬉しい 当時(昨年末くらい)調べた範囲では「これが決定版」という方法は見つからず (もしあれば、是非教えてください) 社内で3つの案が浮かび、最もよさそうなものを選んだ やりたいこと 8
© 2023 estie Inc. それぞれのアイデアと課題 9
© 2024 estie, inc. GraphQLでは、ネストされた構造にフィルター条件を渡せる • 以下のようなスキーマが定義できる • 検索以外では AskingSearchCondition
を渡さずにネストすれば普通にデータ取得できるはず 1. ネストされた構造に条件を渡す 10 こう書ける(一見よさそう)
© 2024 estie, inc. 課題:N+1問題の回避が綱渡り • Building ごとにSQLクエリを発行して askings を取得するとN+1問題が発生
• dataloaderを使って回避したいが、複雑な条件を渡すと処理が難しい 1. ネストされた構造に条件を渡す 11
© 2024 estie, inc. 本当に検索したい対象は Asking なので、それを主役にして設計してみる すなわち、検索クエリの返り値を Asking の配列にする
• Building 主体だと、(Asking を複数持つので)条件を満たす Asking とそうでない Asking が紐づ いているという問題があった • Asking を主体にすれば、(親の Building は一意なので)初めから条件を満たすものを検索してお けば何も気にせずネストして良い 2. Asking主体で返り値を設計する 12
© 2024 estie, inc. 課題:ページネーション処理がやや煩雑 • 建物ごとに表示したいので、建物で括る必要がある • やや面倒だが、これはフロントエンドでやれば良い •
しかしページネーションをどうするか? • 建物の条件で Asking をソートすることは出来る • 表示は1ページあたり「建物20件」なので、募集の件数でページネーションをしても意味がない • ビルの件数をカウントして該当の募集を返すことも出来なくはないが、煩雑に • やはりインターフェースとして不自然か? 2. Asking主体で返り値を設計する 13
© 2023 estie Inc. 解決方法 14
© 2024 estie, inc. • SQLクエリからは、{ building_id, asking_ids } の配列を取得する(ここは頑張る)
• Building に searched_asking_ids というフィールドを持たせる • askings を以下の条件で取得する • searched_asking_ids が未設定→その建物の募集全て • searched_asking_ids が設定済→その募集IDの募集 (詳しくは次のページの実装例で) これにより、 • 表示に合った「建物ごとにまとめられた募集」という形式のインターフェース • dataloaderに渡すクエリが単純なものになり、N+1問題の回避が自然に出来る BuildingからAskingを取得するときに使うための補助的なフィールドを利用する 15
© 2024 estie, inc. 実装例 (Rust) BuildingからAskingを取得するときに使うための補助的なフィールドを利用する 16
© 2024 estie, inc. 比較 17 条件を渡してネスト Asking主体の設計 補助的なフィールド利用 APIインターフェース
Building の配列 そのまま使える 嬉しい Asking の配列 Building ごとにまとめる 微妙 Building の配列 そのまま使える 嬉しい 気になる点 dataloaderの実装が複雑 微妙 ページネーション処理が 煩雑 微妙 補助的なフィールドが 冗長 許容
© 2024 estie, inc. • 多くのネスト構造を持つデータを扱うAPIにとって、GraphQLは便利 • しかし、ネストされたデータに跨った検索条件を扱う検索APIをいい感じにするのがやや難しい • GraphQLのメリットを活かしながらそれを実現する方法を紹介した
• より良い方法があればぜひ知りたいです まとめ 18
ご清聴ありがとうございました