読むべきもの
あとはApollo GraphQLのドキュメントとか。
サーバサイドの人は、DataLoaderを読むべき。スキーマ設計ではないので特に触れない。
スキーマ設計について
グラフ構造
まず、グラフ構造を意識してください。
例として、1ユーザあたりに複数のアイテムを持っているとします。user 1 - N item
以下のようにしてください。
type User {
id: ID!
items: [Item!]!
}
type Item {
id: ID!
}
type Query {
user(id: ID!): User
}
以下は、UserからItemがつながっていない。
type User {
id: ID!
}
type Item {
id: ID!
}
type Query {
user(id: ID!): User
userItems(userId: ID!): [Item!]!
}
ID
リソース(user, postなど)のIDを表現するには、StringやIntなどの型ではなくではなく、ID型を使いましょう。
実装的な話になりますが、IDはユニークである必要があります。
これは、user内でユニークであるという意味ではなく、全体(user, item, etc...)でユニークであると言うことです。
base64でエンコードされた値が使われることでしょう。echo 'user:123' | base64。
cursor based paginationとconnection
ページネーションに関する表現方法です。Node, Edge, Connectionを利用します。
cursorとは、base64でエンコードされたidやConnection内の位置などです。before, afterに渡すことのできる値です。
interface Node {
id: ID!
}
interface Edge {
cursor: String!
node: Node!
}
type PageInfo {
startCursor: String
endCursor: String
hasNextPage: Boolean!
hasPreviousPage: Boolean!
}
interface Connection {
edges: [Edge!]!
pageInfo: PageInfo!
total: Int!
}
type User {
id: ID!
items(
first: Int
last: Int
before: String
after: String
): ItemConnection!
}
type Item implements Node{
id: ID!
}
type ItemEdge implements Edge {
cursor: String!
node: Item!
}
type ItemConnection implements Connection {
edges: [ItemEdge!]!
pageInfo: PageInfo!
total: Int!
}
type Query {
user(id: ID!): User
}
命名規則
camel caseを使います。type, interfaceなどはUpperCamelCase。fieldsはlowerCamelCase。
non-nullを使う
Intのみの配列を表現する際に、[Int]としてしまうと、取りうる値は、[1, 2, null]またnullです。[Int!]!として、Intしか入らない配列を返すようにしましょう。
mutationはInputを受け取り、Payloadを返す
複数の値を渡す・返すのではなく、Input・Payloadにまとめて渡すようにしましょう。
type Mutation {
createItem(input: CreateItemInput!): CreateItemPayload
}
input CreateItemInput {
name: String!
}
type CreateItemPayload {
item: Item
}