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
Prisma2 with Graphql
Search
joe_re
August 28, 2020
1k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Prisma2 with Graphql
GraphqlTokyo #10 LT 資料
joe_re
August 28, 2020
More Decks by joe_re
See All by joe_re
Eyes on Claude Code
joere
0
130
Building Public API with GraphQL
joere
3
140
Traversing the GraphQL AST and Calculating Query Costs
joere
0
1.3k
Real-Time applications with GraphQL
joere
0
300
Go beyound static on Netlify
joere
1
380
Building Real-time Vue App
joere
4
4.7k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
360
Mock Native API in your E2E test
joere
2
1.2k
Data feching and caching on Apollo Client
joere
2
3k
Featured
See All Featured
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
Color Theory Basics | Prateek | Gurzu
gurzu
0
370
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Amusing Abliteration
ianozsvald
1
210
Heart Work Chapter 1 - Part 1
lfama
PRO
7
36k
GraphQLとの向き合い方2022年版
quramy
50
15k
Fireside Chat
paigeccino
42
4k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
We Have a Design System, Now What?
morganepeng
55
8.2k
Transcript
PRISMA2 WITH GRAPHQL @joe_re
INTRODUCTION WHO AM I? ▸ twitter: @joe_re ▸ github: @joe-re
▸ GraphQL Tokyoのオーガナイザの1⼈です ▸ オンラインレッスン/ミーティングのサービスを作っています(@classdo) ▸ Prisma1は結構⻑く使ってきました (Graphcool時代から数えると2年半ぐらい)
PRISMA1 AND PRISMA2 DIFFERENCE OF PRISMA1 AND PRISMA2 ▸ Prisma1はGraphQLのバックエンドサーバ(Prisma
Server)を提供し、 http経由でDBのマイグレーションの指示や、GraphQLクエリとDBクエリの変 換、データの更新や取得を⾏う ▸ Prisma2ではPrisma Serverは撤廃され、アプリケーションコードから直接Prisma Engine(Rust製)というバイナリのAPIを叩いてデータの取得やマイグレーション を⾏う ▸ クライアントのAPIインターフェイスなどは受け継いでいるものの、 アーキテクチャからして全くの別物
* Prisma2のプレビューのアナウンスメントブログより抜粋 https://www.prisma.io/blog/announcing-prisma-2-zq1s745db8i5 PRISMA1 AND PRISMA2
WHAT IS PRISMA2 OVERVIEW OF PRISMA2 ▸ Prisma2ではAPIサーバ側に直接DB接続を持つ ▸ イメージ的にはよりORMに近い動きになる
(ただしPrismaは独⾃DSLに基づいたクライアントのオートジェネレーションや マイグレーションを提供することから⾃身のことをORMではなく database toolkitと位置づけしている)
WHAT IS PRISMA2 OVERVIEW OF PRISMA2 アプリケーションサイド Prisma Client (旧Photon)
クライアントのオートジェネレーションツール Prisma Migrate (旧Lift) 独⾃DSL(.prisma)に基づいたマイグレーション ツール Prisma CLI それぞれのツールの呼び出しのコマンドの提供 Prisma Studio データベースのビジュアルエディタ クエリエンジン Prisma Engine データベースへのクエリエンジン(Rust製) バイナリとして提供されて、アプリケーション サーバに配置される *Prismaの公式ドキュメント、Query Engineのページより抜粋 https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/query-engine
WHAT IS PRISMA2 Q:あれ、GraphQL関係なくね? ▸ はい、ありません
WHAT IS PRISMA2 ▸ Prisma2はPrisma1からクエリエンジンとクライアント(ORM)やマイグレーション やその周辺ツール部分をブラッシュアップしたプロダクト ▸ 基本的にGraphQLとのつながりはない (RestAPIサーバでもCLIツールでもなんで も使える)
▸ GraphQLの実装はNexusを使うことが推奨されている
WHAT IS NEXUS WHAT IS NEXUS ▸ GraphQLのアプリケーションサーバを開発するTypeScriptのフレームワーク ▸ レポジトリはPrismaのオーガナイゼーション配下にはないけど、
ドキュメントに何度も登場したりPrismaの開発者がコントリビュートしていたり ほぼ公式の位置づけ ▸ Schema-First開発をシンプルにして、その利便性とCode-First開発の保守性、 開発の素早さとを両⽴させることを⽬指している
WHAT IS NEXUS DEVELOPMENT GRAPHQL SERVER ON NEXUS ▸ Code-Firstのアプローチで、先にResolverを記述する
(graphql-jsの上で開発していて、⾒た⽬はSDLっぽくなる) ▸ Resolverの記述に伴い、開発サーバがリアルタイムにコードをビルドして、 GraphQLスキーマファイルとそれに対応した型ファイルの⽣成を⾏う ▸ 全てをリアルタイムにビルドする & 完全な型付けを提供することで、 ⼀般的なSchema-Firstにおける、GraphQLスキーマの記述 -> コードジェネレー ションの⼿間を省きつつその利点を得る
WHAT IS NEXUS DEVELOPMENT GRAPHQL SERVER ON NEXUS api/Post.ts (Resolver)
app.graphql node_modules/@type/typegen-nexus/index.d.ts 1. 先にResolverを記述 2. 開発サーバが変更を検知 3-1. GraphQLスキーマファイルの⽣成 3-2. Resolverの型ファイルを⽣成 (node_modules/@types以下に⽣成される)
DEMO
WHAT IS NEXUS THE IMPRESSION OF NEXUS ▸ ⼩さい範囲で試している範囲では快適な体験 ▸
個⼈的にはSchema-First寄りの意⾒を持っていたけど、 このアプローチが上⼿くスケールするならあり (ただし今までPrismaは途中で開発をやめたプロダクトが少なからず あるので少し⼼配) ▸ プロダクトが⼤きくなった時のコードジェネレーションの速度が気になる
時間があればちょっとだけ クエリオプティマイズの話をします
GraphQLでN+1起きがち問題ありますよね??
こんなの ユーザ全件を取得するクエリ定義 ユーザのタイプ定義 (Type Resolver) ユーザ1件に対して1件のProfileを取得する
PRISMA1ではどう解決されていたか ▸ Prisma1ではPrisma Serverへ⾶ぶリクエストがまとめられて、⼀気にサーバ側で 解決される https://github.com/prisma-labs/http-link-dataloader ▸ ⼀⾒N+1が起きそうなコードを書いても、 ある程度のところまでは⾃動でオプティマイズされる (
深刻なパフォーマンスの問題が出ればもちろん真剣に取り組む必要はある) ▸ Prisma1からPrisma2へ移⾏を考える上で検証は避けては通れないところ
試してみた
結果 ▸ 1 つ⽬: ユーザ全体を取得する(params: [-1, 0]) SELECT `dev`.`User`.`id`, `dev`.`User`.`email`,
`dev`.`User`.`name` FROM `dev`.`User` WHERE 1=1 LIMIT ? OFFSET ? ▸ 2つ⽬-4つ⽬: ユーザ単位でポストの全体を取得する (params: [userId, -1, 0]) SELECT `dev`.`Post`.`id`, `dev`.`Post`.`authorId`, `dev`.`Post`.`content`, `dev`.`Post`.`published`, `dev`.`Post`.`title` FROM `dev`.`Post` WHERE (`dev`.`Post`.`id`) IN (SELECT `t0`.`id` FROM `dev`.`Post` AS `t0` INNER JOIN `dev`.`User` AS `j0` ON (`j0`.`id`) = (`t0`.`authorId`) WHERE `j0`.`id` = ?) LIMIT ? OFFSET ? ▸ 5つ⽬: Profile取得対象のユーザの存在を確かめる(?) (params: [1, 2, 3, -1, 0]) SELECT `dev`.`User`.`id` FROM `dev`.`User` WHERE `dev`.`User`.`id` IN (?,?,?) LIMIT ? OFFSET ? ▸ 6つ⽬: Profileの取得(params: [1, 2, 3, -1, 0]) SELECT `dev`.`Profile`.`id`, `dev`.`Profile`.`bio`, `dev`.`Profile`.`userId` FROM `dev`.`Profile` WHERE `dev`.`Profile`.`userId` IN (?,?,?) LIMIT ? OFFSET ? まとめられてる!
気になったのでコードを追ってみたところ、現状はfindOneのクエリはまとめられるようです ▸ Client側のリクエストのバッチ送信処理 https://github.com/prisma/prisma/blob/2.5.1/src/packages/client/src/runtime/Dataloader.ts#L31 ▸ クエリエンジン側のオプティマイゼーションの判定処理 (同じファイルにオプティマイゼーションの処理も ある) https://github.com/prisma/prisma-engines/blob/2.6.0-dev.44/query-engine/core/src/query_document/ mod.rs#L61
▸ GraphQLのResolverで最もN+1が起きやすいコードはこれだと思うので、ここがオプティマイズされるのは 嬉しい ▸ オプティマイズ効かせるのに少しコツがいりそうなので、このあたりもドキュメントになって欲しい気持ち
THANK YOU!