Slide 1

Slide 1 text

GraphQLスキーマの設計で 考えたこと 2022/01/26 Hatena Engineer Seminar #18 id:AnaTofuZ

Slide 2

Slide 2 text

今日の内容

Slide 3

Slide 3 text

GraphQLスキーマの設計は難しい

Slide 4

Slide 4 text

今日の内容 ● GraphQLスキーマの設計は難しい ● DBスキーマと合わせて設計するのが正解? それとも? ● 型やフィールドで何を表現するか ● バックエンド、フロントエンドの事情とスキーマの表現

Slide 5

Slide 5 text

こんにちは ● id:AnaTofuZ ● Webアプリケーションエンジニア ● 2021年新卒 ○ それまでは沖縄にいました ○ 出身は山梨です... ● アカウント名はアナグラです

Slide 6

Slide 6 text

もくじ ● GraphQLとは ● カクヨムとGraphQL ● 1から考えるスキーマ設計 ● まとめ

Slide 7

Slide 7 text

GraphQL ● Facebookによって作られたクエリ言語 ● GraphQLスキーマがある ● スキーマの内扱いたい情報をfragmentで部分的に宣言できる ● オブジェクトの取得はQuery/ 更新はMutationで行う ● 詳しくは ○ GraphQL Highway

Slide 8

Slide 8 text

GraphQL ● Facebookによって作られたクエリ言語 ● GraphQLスキーマがある ● スキーマの内扱いたい情報をfragmentで部分的に宣言できる ● オブジェクトの取得はQuery/ 更新はMutationで行う ● 詳しくは ○ GraphQL Highway

Slide 9

Slide 9 text

GraphQLのスキーマ ● SDL (Schema Definition Language)で 定義する ● interfaceをもつ ○ 開発チームで考えると ■ Interface Member ● 共通部分 ■ Type Engineer ● エンジニア ● 好きなプログラミング言語をもつ ■ Type Designer ● デザイナー ● Adobe IDを必ずもつ interface Member { id: ID! name: String! githubID: String! } type Engineer implements Member { id: ID! name: String! githubID: String! favoriteProgramingLanguage: String } type Designer implements Member { id: ID! name: String! githubID: String! adobeID: String! }

Slide 10

Slide 10 text

GraphQLのスキーマ ● nullable(null許容)な値と non-nullable(非null許容)な値がある ○ 型名の後ろに ! がついているとnon-nullable ○ 👉の例ではid, nameはnon-nullable ■ favoriteProgramingLanguageはnullable ● バックエンド/フロントエンドともに 共通してスキーマを使う ○ 型情報は両者ともに共通して知っている interface Member { id: ID! name: String! githubID: String! } type Engineer implements Member { id: ID! name: String! githubID: String! favoriteProgramingLanguage: String } type Designer implements Member { id: ID! name: String! githubID: String! adobeID: String! }

Slide 11

Slide 11 text

GraphQLのfragment ● GraphQLはfragmentを使うと、必要なデータを 宣言的に定義することができる ● 👉ではInterface Memberの中から必要なデータを WebAccountとして宣言している ○ 全MemberはgithubIDを取得できる ○ … on 型名でInterfaceの具体的な型の場合取得するデータを 宣言することができる ■ Type DesignerならAdobe IDが取得できる fragment WebAccount on Member { id githubID ... on Designer { adobeID } }

Slide 12

Slide 12 text

GraphQLをフロントエンドで使う ● GraphQL Code Generatorなどを使うとスキーマからTypeScriptの型を生成できる ○ スキーマ上の型に対応したTypeScriptの型が生成される ○ fragmentに対応した型(fragmentで拾ってきたい情報)も自動生成される ● スキーマ上の型がTypeScriptの型に直接対応する ○ InterfaceやInterfaceの実装の型はいい感じにTypeScriptの型表現にマッピングされる ○ nullable, non-nullableな型も考慮される ● 先述のfragmentをうまく使うと、コンポーネントに必要なデータをモジュール化できる ○ fragmentはコンポーネントに閉じるので、具体的に何が必要か使う側では知らずに渡せる

Slide 13

Slide 13 text

GraphQLとフロントエンド ● fragmentで引いた値をそのままコンポーネントに渡すことができる ○ GraphQLスキーマとコンポーネント (UI)がうまく対応できるようにスキーマを考える必要がある 👆コンポーネント使う側 👆コンポーネントの引数 memberにfragmentで引いた値をいれるだけでよい interface Props { member: WebAccountFragment; } export const WebAccount: React.VFC = ({ member }) => { return (
{user.__typename === 'Designer' && Adobe ID: {member.adobeID} }
); }; fragment GitHubName on Member { id githubID } 👆コンポーネント定義側 fragment WebAccount on Member { id githubID ... on Designer { adobeID } }

Slide 14

Slide 14 text

GraphQLとフロントエンド ● fragmentで引いた値をそのままコンポーネントに渡すことができる ○ GraphQLスキーマとコンポーネント (UI)がうまく対応できるようにスキーマを考える必要がある 👆コンポーネント使う側 👆コンポーネントの引数 memberにfragmentで引いた値をいれるだけでよい interface Props { member: WebAccountFragment; } export const WebAccount: React.VFC = ({ member }) => { return (
{user.__typename === 'Designer' && Adobe ID: {member.adobeID} }
); }; fragment GitHubName on Member { id githubID } 👆コンポーネント定義側 fragment WebAccount on Member { id githubID ... on Designer { adobeID } } … fragment名で、fragmentに定義され ているデータを持ってくることができる

Slide 15

Slide 15 text

GraphQLとフロントエンド ● fragmentで引いた値をそのままコンポーネントに渡すことができる ○ GraphQLスキーマとコンポーネント (UI)がうまく対応できるようにスキーマを考える必要がある 👆コンポーネント使う側 👆コンポーネントの引数 memberにfragmentで引いた値をいれるだけでよい interface Props { member: WebAccountFragment; } export const WebAccount: React.VFC = ({ member }) => { return (
{user.__typename === 'Designer' && Adobe ID: {member.adobeID} }
); }; fragment GitHubName on Member { id githubID } 👆コンポーネント定義側 fragment WebAccount on Member { id githubID ... on Designer { adobeID } } コンポーネントに必要な fragmentを引い ているので、そのままオブジェクトを渡す ことができる

Slide 16

Slide 16 text

GraphQLとフロントエンド ● fragmentで引いた値をそのままコンポーネントに渡すことができる ○ GraphQLスキーマとコンポーネント (UI)がうまく対応できるようにスキーマを考える必要がある 👆コンポーネント使う側 👆コンポーネントの引数 memberにfragmentで引いた値をいれるだけでよい interface Props { member: WebAccountFragment; } export const WebAccount: React.VFC = ({ member }) => { return (
{user.__typename === 'Designer' && Adobe ID: {member.adobeID} }
); }; fragment GitHubName on Member { id githubID } 👆コンポーネント定義側 fragment WebAccount on Member { id githubID ... on Designer { adobeID } } Interfaceが 特定の型だったときのみ 持ってくるデータが書ける … on Designer と対応した記述ができる (designerだったらAdobe IDを表示する)

Slide 17

Slide 17 text

GraphQLまとめ ● GraphQLにはスキーマがある ● スキーマにはInterface、Interfaceの実装の型がある ● フィールドはnullableとnon-nullableのものがある ● フロントエンドではgraphqlのfragmentを使うとコンポーネント内に必要なデータを 閉じ込めることができる ○ コンポーネントに1オブジェクトだけ渡せば済むようになり最高 ● Interfaceが特定の型だったときに色々する条件がかける ○ 特定のデータを持ってくる、型で分岐が書ける

Slide 18

Slide 18 text

もくじ ● GraphQLとは ● カクヨムとGraphQL ● 1から考えるスキーマ設計 ● 動かしながらスキーマを変更する ● まとめ

Slide 19

Slide 19 text

カクヨム ● KADOKAWA様とはてなで共同開発しているWeb小説サイト ○ Webアプリ以外にスマホアプリも提供している

Slide 20

Slide 20 text

カクヨムとGraphQL ● スマホアプリで先行してGraphQLを利用 ● 最近Webサイト部分でもGraphQLを利用しはじめた

Slide 21

Slide 21 text

もくじ ● GraphQLとは ● カクヨムとGraphQL ● 1から考えるスキーマ設計 ● 動かしながらスキーマを変更する ● まとめ

Slide 22

Slide 22 text

1から考えるスキーマ設計 ● カクヨムの「近況ノート」に新機能を提供予定 ● この新機能を加味したGraphQLスキーマを1から考えた ○ 今日はこのスキーマ設計で考えたことを話します

Slide 23

Slide 23 text

近況ノートとは ● 近況ノート ○ 小説の紹介や更新情報、読書履歴やおすすめ作品の紹介を投稿でき る機能 ○ 最近画像が投稿できるようになった

Slide 24

Slide 24 text

カクヨムロイヤルティプログラム第二弾

Slide 25

Slide 25 text

限定近況ノート ● 普通の近況ノートは誰でも読める ● 限定近況ノートは読めないユーザーもいる ● 共通して次のようなUIを作りたい

Slide 26

Slide 26 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定]

Slide 27

Slide 27 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] 普通の近況ノートは 本文が読める

Slide 28

Slide 28 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] 読めない限定近況ノートはタ イトル + 限定であることがわ かる

Slide 29

Slide 29 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] 読める限定近況ノートは 本文と限定であることが表示 される

Slide 30

Slide 30 text

👉GraphQLスキーマの前に DBスキーマを確認

Slide 31

Slide 31 text

データベース上の限定近況ノートの扱い ● データベース上では限定近況ノートかそうでないかは、近況ノートのテーブルのフラ グで管理している ○ 実際にこの近況ノートが読めるかどうかはバックエンドで管理している ● データベースのスキーマとGraphQLのスキーマを 一致させる目線に立つと、1つの型で表現する必要 性が出てくる id title body is_limited author_account_id

Slide 32

Slide 32 text

👉GraphQLスキーマを設計していくぞ!!!

Slide 33

Slide 33 text

今日の内容 ● GraphQLスキーマの設計は難しい ● DBスキーマと合わせて設計するのが正解? それとも? ● 型やフィールドで何を表現するか ● バックエンド、フロントエンドの事情とスキーマの表現

Slide 34

Slide 34 text

検討1: 1つの型で表現仕切る ● DBの近況ノートのスキーマをGraphQLで表現する形

Slide 35

Slide 35 text

検討1: 1つの型で表現仕切る ● DBの近況ノートのスキーマをGraphQLで表現する形 type UserNewsEntry { id: ID! title: String! body: String isLimited: bool! visitorCanRead: bool! }

Slide 36

Slide 36 text

検討1: 1つの型で表現仕切る ● DBの近況ノートのスキーマをGraphQLで表現する形 ○ 読めないケースもあるので bodyをnull許容 ○ 閲覧者が読めるかどうかを別でもたせた type UserNewsEntry { id: ID! title: String! body: String isLimited: bool! visitorCanRead: bool! }

Slide 37

Slide 37 text

検討1: 1つの型で表現仕切る ● pros ○ 1つの型で表現仕切ることができる ■ DBスキーマと対応 ○ nullableな型をうまく利用している ● cons ○ スキーマ上で「読めない限定近況ノートの場合、必ず本文にアクセスできないこと」 が表現できない ■ ともすればアクセスできてしまうのではという不安 ○ 「限定近況ノートでかつ読めない場合」をフロントで表現しようとすると、判断に必要 なフィールドが多い ■ 型レベルで読める読めないの判断がしづらい ● フロントエンドはTypeScriptで開発しているので型を活かしたい

Slide 38

Slide 38 text

検討2: 普通/限定の近況ノートで型を分ける ● 1つの型ではなくて型を分ける方針で考えた ● 今回の型定義は普通/限定に着目した

Slide 39

Slide 39 text

検討2: 普通/限定の近況ノートで型を分ける interface AbstractUserNewsEntry { id: ID! title: String! } # 普通の近況ノート type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String! } # 限定近況ノート type LimitedUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String # ないケースもあるので null許容 }

Slide 40

Slide 40 text

検討2: 普通/限定の近況ノートで型を分ける interface AbstractUserNewsEntry { id: ID! title: String! } # 普通の近況ノート type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String! } # 限定近況ノート type LimitedUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String # ないケースもあるので null許容 } 共通してアクセス可能な部 分をInterfaceに集約する

Slide 41

Slide 41 text

検討2: 普通/限定の近況ノートで型を分ける interface AbstractUserNewsEntry { id: ID! title: String! } # 普通の近況ノート type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String! } # 限定近況ノート type LimitedUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String # ないケースもあるので null許容 } 普通の近況ノートの場合は 本文は読めるのでbodyは nonnullable

Slide 42

Slide 42 text

検討2: 普通/限定の近況ノートで型を分ける interface AbstractUserNewsEntry { id: ID! title: String! } # 普通の近況ノート type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String! } # 限定近況ノート type LimitedUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がNormal用 body: String # ないケースもあるので null許容 } 対して限定近況ノートの場合 は読めない可能性があるの で本文はnull許容

Slide 43

Slide 43 text

検討2: 普通/限定の近況ノートで型を分ける ● pros ○ 型レベルで普通か限定かを判断できる ■ 共通部分はInterface化しているので扱いやすい ○ nullableな値を活かしている ● cons ○ 限定近況ノートの場合、bodyがnullかどうかで読めるかどうかを判定 する必要がある ○ 画一的にbodyにアクセスしたい場合、分岐が複雑

Slide 44

Slide 44 text

ヨッシャこれで決まり!!

Slide 45

Slide 45 text

ヨッシャこれで決まり!! ではない!!!

Slide 46

Slide 46 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定]

Slide 47

Slide 47 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] body: String!

Slide 48

Slide 48 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] body: String! body: String

Slide 49

Slide 49 text

作りたいUI例 タイトル 本文です タイトル [限定] タイトル 本文です [限定] body: String! body: String bodyの型が コンフリクト

Slide 50

Slide 50 text

このUIを実現しようとするとエラーが ● フロントこのUIを満たすfragmentを定義したところバチバチに怒られる ○ 同じbodyというフィールドなのに型が String!とStringで違うから無理!!! ○ ○ ○ ● Interfaceの実装の型において同名のフィールドは同じ型の方が望ましそう ○ 読めない限定近況ノートの場合は bodyがnullの可能性がある ○ 今回のスキーマのままいくと、普通の近況ノートでも bodyをString!にしなければならない ● 今回は明らかにこのスキーマだと作りたいUIが表現できないので再考 GraphQLDocumentError: Fields "body" conflict because they return conflicting types "String!" and "String". Use different aliases on the fields to fetch both if this was intentional.

Slide 51

Slide 51 text

検討3: 限定近況ノートを読める/読めないで分ける ● フィールドの型を同じにしたい ● 極力型を使って状態を表現したい ○ 近況ノートと閲覧者の状況を素直に型にするのを考えた ● 状態を型にマッピングすることを考えた

Slide 52

Slide 52 text

検討3: 限定近況ノートを読める/読めないで分ける interface AbstractUserNewsEntry { id: ID! title: String! } type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! #近況ノート本文 body: String! } type LimitedUserNewsEntryCanRead implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がLimitedUserNewsEntryCanRead用 body: String! } type LimitedUserNewsEntryCanNotRead implements AbstractUserNewsEntry { id: ID! title: String! } 公開情報をinterfaceに

Slide 53

Slide 53 text

検討3: 限定近況ノートを読める/読めないで分ける interface AbstractUserNewsEntry { id: ID! title: String! } type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! #近況ノート本文 body: String! } type LimitedUserNewsEntryCanRead implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がLimitedUserNewsEntryCanRead用 body: String! } type LimitedUserNewsEntryCanNotRead implements AbstractUserNewsEntry { id: ID! title: String! } 普通の近況ノートは必ず 本文にアクセスできる

Slide 54

Slide 54 text

検討3: 限定近況ノートを読める/読めないで分ける interface AbstractUserNewsEntry { id: ID! title: String! } type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! #近況ノート本文 body: String! } type LimitedUserNewsEntryCanRead implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がLimitedUserNewsEntryCanRead用 body: String! } type LimitedUserNewsEntryCanNotRead implements AbstractUserNewsEntry { id: ID! title: String! } 読める近況ノートも同様 に本文にアクセスできる

Slide 55

Slide 55 text

検討3: 限定近況ノートを読める/読めないで分ける interface AbstractUserNewsEntry { id: ID! title: String! } type NormalUserNewsEntry implements AbstractUserNewsEntry { id: ID! title: String! #近況ノート本文 body: String! } type LimitedUserNewsEntryCanRead implements AbstractUserNewsEntry { id: ID! title: String! # ここから下がLimitedUserNewsEntryCanRead用 body: String! } type LimitedUserNewsEntryCanNotRead implements AbstractUserNewsEntry { id: ID! title: String! } 読める近況ノートも同様 に本文にアクセスできる 読めない限定近況ノート はInterfaceの内容(公開 情報)しかアクセス出来 ない

Slide 56

Slide 56 text

検討3: 限定近況ノートを読める/読めないで分ける ● pros ○ 読めない場合にアクセスできない範囲がスキーマで十分表現できてい る ■ 逆に読める場合にアクセスできる範囲も表現できている ○ 型の状況と近況ノートの状態がマッチしている ● cons ○ 型が多い!!!!!!

Slide 57

Slide 57 text

型が多いことによる問題 Normal LimitedCanRead Limited CanNotRead 読める近況ノート 限定近況ノート

Slide 58

Slide 58 text

型が多いことによる問題 Normal LimitedCanRead Limited CanNotRead 読める近況ノート 限定近況ノート 型と状態のグループ分けをバックエンド /フロントエンド共に行わないといけない !!! 👉 状態を決定する責務がバックエンド /フロントに散ってしまう

Slide 59

Slide 59 text

再考

Slide 60

Slide 60 text

検討4: 読める/読めないでの型定義 ● 閲覧者が対象の近況ノートを読めるか読めないかで型を分けることを考えた ● 限定近況ノートはフィールドで表現する

Slide 61

Slide 61 text

interface AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } # 本文を読むことができる近況ノート type ReadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! # 以下 ReadableUserNewsEntry用 # 近況ノート本文 body: String! } # 本文を読むことができない近況ノート # 公開情報しか参照することができない type UnreadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! }

Slide 62

Slide 62 text

interface AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } # 本文を読むことができる近況ノート type ReadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! # 以下 ReadableUserNewsEntry用 # 近況ノート本文 body: String! } # 本文を読むことができない近況ノート # 公開情報しか参照することができない type UnreadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } 常にアクセスできる公開情報を Interfaceとして定義

Slide 63

Slide 63 text

interface AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } # 本文を読むことができる近況ノート type ReadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! # 以下 ReadableUserNewsEntry用 # 近況ノート本文 body: String! } # 本文を読むことができない近況ノート # 公開情報しか参照することができない type UnreadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } 常にアクセスできる公開情報を Interfaceとして定義 限定近況ノートであるかどうかは Booleanのフィールドとして定義

Slide 64

Slide 64 text

interface AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } # 本文を読むことができる近況ノート type ReadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! # 以下 ReadableUserNewsEntry用 # 近況ノート本文 body: String! } # 本文を読むことができない近況ノート # 公開情報しか参照することができない type UnreadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } 読める近況ノート == 必ず本文に アクセスできるのでnonnullで宣言 している

Slide 65

Slide 65 text

interface AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } # 本文を読むことができる近況ノート type ReadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! # 以下 ReadableUserNewsEntry用 # 近況ノート本文 body: String! } # 本文を読むことができない近況ノート # 公開情報しか参照することができない type UnreadableUserNewsEntry implements AbstractUserNewsEntry { id: ID! author: User! title: String! # 限定近況ノートであるかどうか isLimited: Boolean! } 読める近況ノート == 必ず本文に アクセスできるのでnonnullで宣言 している 読めない近況ノートは公開範囲 (Intefaceに定義されている内容 )し かアクセスできない

Slide 66

Slide 66 text

検討4: 読める/読めないでの型定義 ● pros ○ 読めない場合にアクセスできない範囲がスキーマで十分表現できてい る ■ 逆に読める場合にアクセスできる範囲も表現できている ○ 型の恩恵がフロントエンドで得やすくなった ■ 例えば「読める場合は特定のUIをだす」のような分岐が簡単 ○ 読める/読めない判定が完全にバックエンドの責務になっている ○ 型での表現とフィールドを使った表現のバランスを取っている ● cons ○ Interfaceっぽくはない使い方....

Slide 67

Slide 67 text

フロントエンドでも安心 ● bodyにアクセスしたい場合は必ずReadableであることを示す必要がでる ○ 型の絞り込みをせずにフィールドにアクセスするとエラーになる ○ TypeScriptで開発している限りは型で安心してコードが書ける

Slide 68

Slide 68 text

最終的なスキーマ ● 「読める/読めないで型を分ける」を採用した ○ バックエンドは閲覧者の状況によって型をいい感じに返すように ○ 型を分けたことで必ず公開情報しかクライアントに渡らないような安心感が得られた ● 今日プロフィールページがReactで動くようになったので実際に動作するように

Slide 69

Slide 69 text

もくじ ● GraphQLとは ● カクヨムとGraphQL ● 1から考えるスキーマ設計 ● まとめ

Slide 70

Slide 70 text

まとめ ● 素朴にDBスキーマと合わせるのが必ずしも正解ではない ● 型で表現するのとフィールド(素朴なbooleanなど)で表現した方が自然なのかはモ ノによって異なる ○ 近況ノートでは読めるかどうかは型にすることでアクセス制限が作れた ○ 限定近況ノートかどうかはフィールドで判断することで素直にアクセス出来た ● スキーマの構成はフロントエンドの使われ方も考慮する必要がある ○ 実現したいUIをスキーマで素朴に表現できるのか ○ 使ってみるとエラーが出るケースがある ○ バックエンド/フロントエンドの責務とスキーマが自然に対応しているか