select_arrow
  • development

GraphQL Coding Style Guide

174
  • 1
  • 0

原則

Naming

フィールド名

camelCase にしてください。

定義の際にmodel本来の名前と変える必要がありますが、クライアントサイド言語(JS, Swift, Java)はcamel caseが基本なので、そのまま使えるというメリットがあります。

なお camel case はいくつかのバリエーションがありますが ActiveSupport の String#camelize(:lower) に準じるようにしてください。

ruby
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) に準じるようにしてください。

ruby
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を取得すべきです。

Collection Type

コレクション型(≒配列)は、GraphQLの生の配列ではなくRelayのconnection型を使います。

これは、edgesとnodeというラッパーオブジェクトのあるデータ型です。

たとえばKibelaのnotifiationsはこんな感じのリクエストをすると:

graphql
query {
  notifications(first: 5) {
    edges {
      node {
        id
        sender {
          account
          avatarSrcSet
        }
        messageHtml
        updatedAt
      }
    }
  }
}

こんな感じのresponseになります:

json
{
  "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 というフィールドを持っています。

例:

graphql
query {
  notifications(state: "UNREAD") {
    totalCount
  }
}

notifications直下に直接配列を置いている場合、totalCountは提供できません。

エラー

エラーは errors.extensions.code でエラーコードを通知してください。クライアントはエラーコードと errors.extensions に含まれる情報を使ってクライアントサイドでユーザー向けのメッセージを構築してください。

errors.message にはAPI利用者(開発者)向けのメッセージを入れてください。

なお、Kibelaでは典型的なエラーは GraphqlError module に定義しています。

Testing

spec/graphql/ に、 type / mutation ごとにspecを書いてください。