LoginSignup
12
3

More than 5 years have passed since last update.

Apollo+Expressで始めるGraphQL超入門 ~ データ取得Lv2

Posted at

あらすじ

1.Apollo+Expressで始めるGraphQL超入門 ~ GraphQLをざっくり理解する
2.Apollo+Expressで始めるGraphQL超入門 ~ データ取得Lv1

GraphQLの設計について

GraphQLの作者の言葉をお借りすると「GraphQLはできるだけ薄く保つ」ということなので、ネストは深くしないのが望ましい。

なぜか

実際に私が陥った例を挙げると、簡易ECサイトをGraphQLで実装しようとしたとき
UserItemを買ったときの履歴PurchaseHistoryをGraphQLで取得できるAPIを作ろうと思った

type User {
  id: ID!
  name: String!
  purchase_history: [Item]
}
type Item {
  id: ID!
  name: String!
  catch_copy: String
}

Userの型に購入履歴をはじめからぶら下げる形で実装しようとした。

しかし、これでは Useridname だけ取得したい時に購入履歴まで取得するロジックが走ってしまう。
大体、購入履歴といえばItemとのリレーションされたデータであり取得コストが大きいため
いくらキャッシュされるとはいえ、必要な情報だけが走る形で実装するのが望ましい。

どうするのか

GraphQLはQueryをまとめることができるので、薄く作ってあるQueryたちをまとめてほしい情報が取得できるQureyを新たに作る。

バックエンドで実装されているQuery

type Query {
  user(id: String!): User
  purchase_history(user_id: String!): [Purchase]
}

user → IDやユーザー名など取得できる
purchase_history → ユーザーの購入履歴が取得できる
各Qureyはそれぞれ user_id を指定すればユーザーの情報を取得できる

しかし、このまま使ってしまうとリクエストを2つになってしまうため、GraphQLの特性を活かしきれていない。

Queryを1つにまとめる

userpurchase_history を1つのQueryで取得できるようにQueryを定義してあげよう

query getUserPurchaseHistory($user_id: String) {
  user(id: $user_id) {
    id
    name
  }
  purchase_history(user_id: $user_id) {
    id
    name
    catch_copy
  }
}

getUserPurchaseHistory に対して user_id を渡すことで1つのリクエストで2つの情報をまとめて取得できる。
こうすることで、必要な情報を必要なときに取得でき、コストの掛かる処理も必要な時だけ行うことができる。

まとめ

またGraphQLの凄さを知ることができ、 GraphQLはできるだけ薄く保つ の意味や意図が理解できました。

設計次第ではネストが深くなってしまい、部分的にしか使わないQueryが量産されてしまうこともあると思います。
そうなってしまうとGraphQLの良さがなくなってしまうので一旦立ち止まって できるだけ薄く を意識することが大事ですね。

※ 筆者はまだまだ初心者です。間違った解釈や実装などがあればご指摘お願いします。

12
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3