user(id:$id) {
id
name
createdAt
updatedAt
}
必要なフィールドのみ取得
- 呼び出し元ではnameしか使わない
Slide 6
Slide 6 text
user(id:$id) {
id
name
}
必要なフィールドのみ取得
- 呼び出し元ではnameしか使わない
- 使うフィールドのみ指定
- 例外としてidフィールドは後に説明する
キャッシュのキーとして使⽤するのでキャッ
シュを活⽤するなら取得すべき
Slide 7
Slide 7 text
無駄な処理
Slide 8
Slide 8 text
user(id:$id) {
id
reviewCount
}
無駄な計算
# Ruby code
def resolve(id:)
user = User.find_by(id:)
{
id: user.id,
review_count: user.reviews.count,
}
end
Slide 9
Slide 9 text
user(id:$id) {
id
reviewCount
}
無駄な計算
– users
select * from users where id = 1;
– reviews
select count(*) from reviews
where user_id = 1;
Slide 10
Slide 10 text
user(id:$id) {
id
}
無駄な計算
– reviewCountを指定していなくても
reviews.countが計算される
# Ruby code
def resolve(id:)
user = User.find_by(id:)
{
id: user.id,
review_count: user.reviews.count,
}
end
Slide 11
Slide 11 text
user(id:$id) {
id
}
無駄な計算
– reviewCountを指定していなくても
reviews.countが計算される
# Ruby code
def resolve(id:)
User.find_by(id:)
end
# Userモデルのメソッドとして提供して呼ばれ
たときだけ取得する
def review_count
reviews.count
end
Slide 12
Slide 12 text
遅延ロード
Slide 13
Slide 13 text
users {
id
profile {
name
}
}
遅延ロード
– id fieldはusersテーブルから取得
– profileはprofilesテーブルから取得
# Ruby code
def resolve
User.all
end
Slide 14
Slide 14 text
users {
id
profile {
name
}
}
遅延ロード
– usersは10件Hit
select * from users;
– profilesを1件ずつ取得 => N+1問題
select * from profiles where user_id = 1;
select * from profiles where user_id = 2;
…
select * from profiles where user_id = 10;
Slide 15
Slide 15 text
users {
id
profile {
name
}
}
遅延ロード
– usersに対応するprofileを事前ロード
# Ruby code
def resolve
User.all.preload(:profile)
end
Slide 16
Slide 16 text
users {
id
profile {
name
}
}
遅延ロード
– usersは10件Hit
select * from users;
– hitしたusersに対応したprofilesを事前ロード
select * from profiles
where user_id in (1, 2, …, 10);
Slide 17
Slide 17 text
users {
id
}
遅延ロード
– usersは10件Hit
select * from users;
– fieldに指定していなくてもprofilesを事前ロー
ドしてしまう
select * from profiles
where user_id in (1, 2, …, 10);
Slide 18
Slide 18 text
users {
id
profile {
name
}
}
遅延ロード
– usersに対応するprofileを遅延ロード
# Ruby code
def resolve
# fieldにprofileがある場合、profile
を取得するuser_idを記憶しておき、最後にま
とめて取得する
User.all
end
Slide 19
Slide 19 text
キャッシュの活⽤
Slide 20
Slide 20 text
user(id:$id) {
__typename
id
name
}
キャッシュの活用
- キャッシュを活⽤することで1度取得した
データはバックエンドに問い合わせずに瞬時
に表⽰できる
- ※APOLLOの場合
- https://www.apollographql.com/docs/react/data/
mutations
- `__typename`と`id`でデータをキャッシュ
Slide 21
Slide 21 text
mutation UpdateUser(input:UpdateUserInput!) {
updateUser(input:$input) {
id
name
}
}
- Mutationのレスポンスで変更後の値を受け取ることで、キャッシュが更
新される
- 明示的にrefetchしなくてもOK
キャッシュの活用