Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
by
yud0uhu
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
Next.js×Prisma×GraphQL×Supabase (+WASM)でブログを⾃作した話 ⼤坂 友
Slide 2
Slide 2 text
© DMM 自己紹介 • 大坂 友 • 2023年4月新卒入社 • 所属:動画配信開発部プレミアムグループブラウザチーム • 出身:北海道 • 趣味:映画鑑賞・旅行・アニメ・趣味開発 etc 2
Slide 3
Slide 3 text
© DMM 今日お話すること・しないこと お話すること • なぜ自作したのか • 使用技術の紹介 ⭕フロントエンド、BFF、WASM ❌マークダウンパーサーの仕組みについて 3
Slide 4
Slide 4 text
© DMM 作ったもの 4
Slide 5
Slide 5 text
© DMM ブログの機能〜inspired Zenn〜 5 できること ⭕キーワード検索 ⭕タグ検索 ⭕記事の投稿 ⭕GitHubログイン(自分のみ) ⭕記事の削除 ⭕ダークモード できないこと ❌アイキャッチの設定 ❌記事の公開予約 ❌画像のアップロード
Slide 6
Slide 6 text
© DMM 6 つくったもの yud0uhu.work
Slide 7
Slide 7 text
© DMM 使用技術 7
Slide 8
Slide 8 text
© DMM 使用技術 8 JSフレームワーク / 言語 Next.js / Type Script 状態管理ライブラリ Apollo Client CSSライブラリ styled-components emotion mantine DB Supabase / Vercel postgress デプロイ先 Vercel 認証・認可 NextAuth ドメイン取得 Cloudflare Registrar
Slide 9
Slide 9 text
© DMM なぜ自作したのか? 9 車輪の再開発が好き • フレームワークは中身がブラックボックスになりがち • 自作すれば、仕組みを理解しながらものづくりができる • 自作はロマンがある • Rustでマークダウンパーサーを自作して、 WASM+Nuxt3+Viteで動かしてみた • Rustで作るリアルタイムOS
Slide 10
Slide 10 text
© DMM ライブラリ選定について 10 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方 法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
Slide 11
Slide 11 text
© DMM ライブラリ選定について 11 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方 法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
Slide 12
Slide 12 text
© DMM GraphQLのN+1問題 12 • サーバ実装で発生しがちなパフォーマンス上の課題 • GraphQLの強みは、クライアントが必要なデータのみをリクエスト し、一度に取得できること • この特性が原因で、N+1問題が発生する
Slide 13
Slide 13 text
© DMM GraphQLのN+1問題 13 以下のようなスキーマについて考える
Slide 14
Slide 14 text
© DMM GraphQLのN+1問題 14 以下のようなスキーマについて考える
Slide 15
Slide 15 text
© DMM GraphQLのN+1問題 15 以下のようなSQLクエリが発行される
Slide 16
Slide 16 text
© DMM GraphQLのN+1問題 16 • 1回のリクエストで、全ての作者を取得するクエリ(authors)が実 行される(1回のリクエスト) • 各作者ごとに、その作者が投稿した記事を取得するために個別のク エリpostsが発行される(5回のリクエスト) 計6回のリクエストが行われる(N+1)
Slide 17
Slide 17 text
© DMM GraphQLのN+1問題 17 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する etc
Slide 18
Slide 18 text
© DMM GraphQLのN+1問題 18 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する etc
Slide 19
Slide 19 text
© DMM Prismaについて 19 • Graphqlと高い親和性を持つORM
Slide 20
Slide 20 text
© DMM Prismaについて 20 • Prismaでは、モデル間のリレーションシップを簡単に定義できる仕 組みが提供されている • Nested reads • Eager Loading • 一度のクエリで、全ての作者とそれぞれの作者が投稿した記事の情 報を取得できる • リレーションのネスト構造が深すぎたり、大量のバッチ処理が必要 となった場合は、N+1問題を完全に解決することが難しい
Slide 21
Slide 21 text
© DMM Pothos(ポトス)について 21 • コードファーストにGraphQLサーバーの開発を行うためのライブラ リ • 元の名前はGiraphQL • 視認性・検索性の問題から改名された • Prismaと互換性があり、N+1問題の対策を強化することができる
Slide 22
Slide 22 text
© DMM supabaseについて 22 • Firebase代替として注目されているOSSのBaaS • 以下の機能を提供している • Database • PostgreSQLベースのRDB • Authentication • Storage • Edge Functions
Slide 23
Slide 23 text
© DMM supabaseについて 23 • Free Plan(従量課金なし) • APIリクエストは無制限 • 500MBまでのデータベース、1GBのファイルストレージが利用 可能 • 最大5GBの帯域幅 • 月間アクティブユーザーは最大50,000人まで • 同時リアルタイム接続の上限は200 • リアルタイムメッセージの上限は最大2,000,000件 • 7日間未利用の場合、サーバの一時停止 • 作成できるプロジェクト数は2つまで
Slide 24
Slide 24 text
© DMM supabaseについて 24 • Vercel Postgres(hobbby plan)との比較 supabse free plan vercel postgres 1ヶ月のAPIリクエスト数 無制限 30,000 1ヶ月のストレージ容量 1GB 256 MB 1ヶ月のデータ転送量 5GB 256 MB 作成できるデータベース数 1 2
Slide 25
Slide 25 text
© DMM supabaseについて 25 schema.prisma Schema Visualizer
Slide 26
Slide 26 text
© DMM prisma+supabase所見 26 • 一つの共通言語(SDL)からGraphQLのスキーマ・DBのテーブルが 一気に生成できて、ER図のビジュアル化ができるため開発体験が良 かった • NoSQLのFirerestoreに対して、supabaseはPostgreSQLベースな のがうれしい • supabaseはFree planでも、個人開発の素振りに使う分にはほどよ い
Slide 27
Slide 27 text
© DMM WASMをVercelでビルドする 27 • ビルドツールはwasm-pack を採用 • 静的アセットを生成するバンドラー • RustのコードからTypeScriptの型定義コードまでを吐き出 してくれる • 内部でwasm-bindgenを利用して、JavaScriptからRust APIを 呼び出すことができる
Slide 28
Slide 28 text
© DMM WASMをVercelでビルドする 28 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2. vercel.jsonでそれを実行するように設定する
Slide 29
Slide 29 text
© DMM WASMをVercelでビルドする 29 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2. vercel.jsonでそれを実行するように設定する
Slide 30
Slide 30 text
© DMM WASMをVercelでビルドする 30 3. Vercelでビルドする
Slide 31
Slide 31 text
© DMM Appendix 31
Slide 32
Slide 32 text
© DMM アクセシビリティ対策 32 • Next.jsのHTMLタグに動的にlangを設定する
Slide 33
Slide 33 text
© DMM アクセシビリティ対策 33 • Next.jsのpagesコンポーネントは、デフォルトでタグと タグを定義してくれる • そのため、_document.jsを作成し、デフォルトのDocumentをオー バーライドしてカスタマイズする
Slide 34
Slide 34 text
© DMM アクセシビリティ対策 34 • 今回はEmotionとstyled-componentsを使用しているため、以下の ドキュメントを参考にrenderPageのカスタマイズを行う • Routing: Custom Document | Next.js
Slide 35
Slide 35 text
© DMM アクセシビリティ対策 35 スコアが改善された🎉
Slide 36
Slide 36 text
© DMM ハイドレーションエラー対策 36
Slide 37
Slide 37 text
© DMM ハイドレーションエラー対策 37 ハイドレーションエラーはなぜ起こるのか • サーバーから事前にレンダリングされたReactツリーと、ブラウ ザーでの最初のレンダリング (Hydration/ハイドレーション) 中に レンダリングされたReactツリーの間に違いが生じたため • 今回のケースだと、classNameの不一致 参考記事 • hydrateRoot – React
Slide 38
Slide 38 text
© DMM ハイドレーションエラー対策 38 ハイドレーションとは • サーバから受け取った「乾いたHTML」に、クライアントサイドの インタラクティブな機能を注ぎ込むこと ハイドレーションエラーとは • 「サーバから受け取った初期HTML」と「クライアントサイドJSが 予期するHTML」が一致しない場合に起こるエラー 参考記事 • 7歳娘「パパ、ReactのHydration Errorってなんで起こるの?」 - Qiita
Slide 39
Slide 39 text
© DMM ハイドレーションエラー対策 39 対策:Pre-rendering and Data Fetching | Learn Next.js を参考に、 フックを使用してレンダリングのタイミングを意図的に制御
Slide 40
Slide 40 text
© DMM 40 まとめ 今後やりたいこと • LightHouseのスコア改善 • アプローチ→FirebaseやGoogle Analytics、New Relicなどで モニタリング&改善の試作 • 目標→スコアオール100点 • 機能拡張 • プロフィールページの作成など
Slide 41
Slide 41 text
© DMM ご静聴ありがとうございました🎉