原則
- GraphQL official site に従う
- GraphQLに足りない部分は Relay に従う
- 実例としてはGraphQL+Relayで構築されているGiHub API v4を参考にする
Naming
フィールド名
camelCase
にしてください。
定義の際にmodel本来の名前と変える必要がありますが、クライアントサイド言語(JS, Swift, Java)はcamel caseが基本なので、そのまま使えるというメリットがあります。
なお camel case はいくつかのバリエーションがありますが ActiveSupport の String#camelize(:lower)
に準じるようにしてください。
puts "content_html".camelize(:lower) # => "contentHtml"
HTMLをもつフィールド
フィールドの値がHTMLの場合は、 Html
というサフィックスを付けてください。
例: blogs.content
(markdown) vs blogs.contentHtml
(HTML)
※ GitHub API v4では HTML
というサフィックスですが、 String#camelize
の結果を使いたい(=ルールに人の判断をいれたくない)のでこのようにします。
タイプ名
タイプ名は UpperCamelCase
にしてください。
なお camel case はいくつかのバリエーションがありますが ActiveSupport の String#camelize(:upper)
に準じるようにしてください。
puts "update_note_mutation".camelize(:upper) # => "UpdateNoteMutation"
Enum
Enumのそれぞれの値は大文字の SNAKE_CASE
にしてください。
ID
データベースのレコードIDそのままではなく、global unique id (Relay ID) を生成してそれを使います。これにより、refetchingが容易になります。
RelayUtility
/ RelayIdentifiable
がRelay IDを生成するための仕組みを提供しています。
なお、このようなIDであるため、クライアントサイドでURL / pathを構築できません。GraphQL responseなどに必要なURL / pathを取得すべきです。
- https://facebook.github.io/relay/docs/graphql-object-identification.html
- http://graphql-ruby.org/relay/object_identification.html
Collection Type
コレクション型(≒配列)は、GraphQLの生の配列ではなくRelayのconnection型を使います。
これは、edgesとnodeというラッパーオブジェクトのあるデータ型です。
たとえばKibelaのnotifiationsはこんな感じのリクエストをすると:
query {
notifications(first: 5) {
edges {
node {
id
sender {
account
avatarSrcSet
}
messageHtml
updatedAt
}
}
}
}
こんな感じのresponseになります:
{
"data": {
"notifications": {
"edges": [
{
"node": {
"id": "Tm90aWZpY2F0aW9uLzE4MQ",
"sender": {
"account": "member_user",
"avatarSrcSet": "{\"1x\":\"/assets/avatar/avatar3-xxx.svg\",\"2x\":\"/assets/avatar/avatar3-xxx.svg\"}"
},
"messageHtml": "<strong>member_user</strong> has <strong>commented</strong> on <span class=\"notification-entryTitle\">foo bar</span>.",
"updatedAt": "2017-09-07T15:54:04+09:00"
}
}
]
}
}
}
edgesとnodeというラッパーがあると冗長にみえますが、それぞれのレイヤにカスタムデータを差し込めるようにするためです。たとえば、notifications(や、ほかの多くのKibelaのデータ型)は素のconnection型を拡張して edges.totalCount
というフィールドを持っています。
例:
query {
notifications(state: "UNREAD") {
totalCount
}
}
notifications直下に直接配列を置いている場合、totalCountは提供できません。
エラー
エラーは errors.extensions.code
でエラーコードを通知してください。クライアントはエラーコードと errors.extensions
に含まれる情報を使ってクライアントサイドでユーザー向けのメッセージを構築してください。
errors.message
にはAPI利用者(開発者)向けのメッセージを入れてください。
なお、Kibelaでは典型的なエラーは GraphqlError
module に定義しています。
Testing
spec/graphql/
に、 type / mutation ごとにspecを書いてください。