0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQLのスキーマ設計メモ

Posted at

読むべきもの

あとは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
}
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?