Open1

【GraphQL】スキーマの設計 - コネクションとリストについて

yu.miyoshiyu.miyoshi

概要

GraphQLコネクションとリストについてまとめる

GraphQLのスキーマを作成するとき、フィールドにGraphQLの型のリストを指定することができる。
リストはGraphQLの型を大括弧で囲むことで表現できるので、

[String]

と記述することでString型のリストを表すことができる。

一対一の接続

カスタムオブジェクト型のフィールドを定義するときには、2つのオブジェクトを接続することになる。
例えば、PhotoはUserによって投稿されるイメージ。
この接続部分のことをエッジと呼ぶそうなので、以後この言葉を使っていきます。
Photoはその投稿者であるUserとの間にエッジがあるはずで、以下のようにスキーマを定義する。

type User {
  githubLogin: ID!
  name: String
  avatar: String
}

type Photo {
  id: ID!
  name: String!
  url: String!
  description: String
  created: Datetime!
  category: PhotoCategory!
  postedBy: User!
}

スキーマに新しい型を定義し、それをPhotoにpostedByフィールドを追加し、2つの型を接続する。
この場合、すべてのPhotoには必ず投稿者(User)が存在するため、末尾にビックリマークを追加した。

一対多の接続

GraphQLは基本的に向無グラフ(各枝の始点と終点がどちらであるかを気にしないグラフ)にしておくべき
これを実現するために、User型とPhoto型の間に双方向にエッジを作成する。

type User {
  githubLogin: ID!
  name: String
  avatar: String
  postedPhotos: [Photo!]!
}

※[Photo!]! → nullではないリストで中身はnullではないPhoto型
User型にpostedPhotosフィールドを追加することで、UserからPhotoに向かうエッジを形成できた。
postedPhotosフィールドはPhotoのリストを返すことになる。

多対多の接続

ノードのリストとノードのリストを接続したい場合(例:写真共有アプリで投稿された写真に写っているUserを登録する機能。いわゆるタグ付け)は、Photoは多くのUserから構成され、Userは多くのPhotoにタグ付けされるようになる。

このような接続を実現するためには、UserとPhotoの両方にお互いのリストのフィールドを追加する必要がある。

type User {
  ......
  inPhotos: [Photo!]!
}

type Photo {
  ......
  taggedUsers: [User!]!
}

双方向に一対多の接続を定義し、多対多の接続が表現できる。

参考サイト

初めてのGraphQL