現在、サービスのGraphQLスキーマは、GraphQL SDL(スキーマ定義言語)と呼ばれるものを使用して指定されることがほとんどです。これは、単にGraphQLスキーマ言語と呼ばれることもあります。 これは、スキーマを非常に簡潔に定義できる非常に単純な構文の言語です。 SDLのさまざまな構文要素に息を呑むと、すぐにスキーマを記述できるようになります。

基礎

単純なtodoアプリの基本的なGraphQLスキーマ定義は次のようになります。

# Enumeration type for a level of priority
enum Priority {
  LOW
  MEDIUM
  HIGH
}

# Our main todo type
type Todo {
  id: ID!
  name: String!
  description: String
  priority: Priority!
}

type Query {
  # Get one todo item
  todo(id: ID!): Todo
  # Get all todo items
  allTodos: [Todo!]!
}

type Mutation {
  addTodo(name: String!, priority: Priority = LOW): Todo!
  removeTodo(id: ID!): Todo!
}

schema {
  query: Query
  mutation: Mutation
}

ここでは多くのことが行われているので、最も重要なことのいくつかを分解してみましょう。

オブジェクトタイプ

オブジェクトタイプはGraphQLサービスに固有であり、 type キーワードで定義され、慣例により大文字で始まります。 これらは、タイプ名とそのタイプの下に存在するフィールドを定義します。 オブジェクトタイプの各フィールドは、他のオブジェクトタイプまたはスカラータイプのいずれかに解決できます。 スカラー型は実際のデータを指し、グラフの葉を表します。

上記のスキーマ定義には、 Todo オブジェクトタイプと、QueryおよびMutationルートオブジェクトタイプがあります。 すべてのGraphQLスキーマで必要なのはQueryルートタイプのみですが、サービスでデータの更新、追加、または削除が許可されている場合は、ほとんどの場合、ミューテーションルートタイプも存在します。 さらに、 Subscription ルートタイプも使用可能で、クライアントがサブスクライブできる操作を定義します。

ビルトインスカラータイプ

GraphQLには、 Int Float String Boolean IDの5つの組み込みスカラー型があります。 。 オブジェクト型とは対照的に、スカラー型は実際のデータを指します。 ID タイプは文字列に解決されますが、一意の値が必要です。

列挙型

列挙型を使用すると、型の可能な値の特定のサブセットを定義できます。 前の例では、 Priority 列挙型は、 LOW MEDIUM 、または HIGH の値を取ることができ、それ以外の場合は、検証エラー。 クライアントでは、文字列は列挙型の値を提供するために使用されます。

タイプ修飾子

上記の例からもわかるように、[…]などの文字を使用して、フィールドが解決されるタイプに修飾子を使用できます。 例としてStringスカラー型を使用した内訳は次のとおりです。

  • String :null許容文字列(解決される値は null の場合があります)
  • String!:null許容でない文字列(解決された値がnullの場合、エラーが発生します)
  • [String] :null許容文字列値のnull許容リスト。 値全体をnullにすることも、特定のリスト要素をnullにすることもできます。
  • [String!] :null許容でない文字列値のnull許容リスト。 その場合、値全体を null にすることができますが、特定のリスト要素をnullにすることはできません。
  • [String!]!:null許容でない文字列値のnull不可能なリスト。 null にすることはできず、値全体も個々のアイテムもできません。 空のリスト( [] )は、値全体が null ではなく、個々の null 値がないため、引き続き有効です。

コメントコメント

コメントは記号で追加され、1行のコメントのみが許可されます。

カスタムスカラータイプ

次のような構文でカスタムスカラー型を定義することもできます。

scalar DateTime

ただし、これを使用すると、GraphQLサービスは、カスタムスカラーをシリアル化して検証する方法を定義する必要があります。

共用体の種類

共用体型は、いくつかの可能なオブジェクト型に解決できる型を定義します。

# ...

union Vehicule = Car | Boat | Plane

type Query {
  getVehicule(id: ID!): Vehicule!
}

共用体タイプの場合、クライアントでは、解決されるサブタイプに応じて、インラインフラグメントを使用して目的のフィールドを選択する必要があります。

query {
  getVehicule {
    ...on Car {
      year
    }
    ...on Boat {
      color
    }
    ...on Plane {
      seating
    }
  }
}

インターフェース

インターフェイスは共用体型にいくぶん似ていますが、複数のオブジェクト型がいくつかのフィールドを共有できるようにします。

interface Vehicule {
  color: String
  make: String
  speed: Int
}

type Car implements Vehicule {
  color: String
  make: String
  speed: Int
  model: String
}

# ...

インターフェイスを実装する各タイプには、インターフェイスのすべてのフィールドに対応するフィールドが必要ですが、独自の追加フィールドを持つこともできます。 このように、クライアントでは、インラインフラグメントを使用して、特定のタイプに固有のフィールドを取得できます。

graphql {
  getVehicule {
    color
    make
    ...on Car {
      model
    }
  }
}

入力タイプ

クエリまたはミューテーションで複数の引数が必要な場合、各フィールドが引数を表す入力タイプを定義する方が簡単な場合があります。

# ...

input NewTodoInput {
  name: String!
  priority: Priority = LOW
}

type Mutation {
  addTodo(newTodoInput: NewTodoInput!): Todo!
  removeTodo(id: ID!): Todo!
}

スキーマドキュメント

タイプとフィールドの人間が読める形式のドキュメントを追加する構文もあります。これは、GraphiQLGraphQLPlaygroundなどのツールを使用してスキーマのドキュメントを参照するときに非常に役立ちます。

最初のtodoスキーマの例を取り上げて、タイプといくつかのフィールドのドキュメントを追加しましょう。

"""
Priority level
"""
enum Priority {
  LOW
  MEDIUM
  HIGH
}

type Todo {
  id: ID!
  name: String!
  """
  Useful description for todo item
  """
  description: String
  priority: Priority!
}

"""
Queries available on the todo app service
"""
type Query {
  """
  Get one todo item
  """
  todo(id: ID!): Todo
  """
  List of all todo items
  """
  allTodos: [Todo!]!
}

type Mutation {
  addTodo(
    "Name for the todo item"
    name: String!
    "Priority levl of todo item"
    priority: Priority = LOW): Todo!
  removeTodo(id: ID!): Todo!
}

schema {
  query: Query
  mutation: Mutation
}

ご覧のとおり、タイプまたはフィールドのドキュメントは、*“” “…“”“*構文でラップすることによって追加されます。 *”…”*は、引数に関するドキュメントに使用されます。

これにより、GraphQLスキーマを定義することで競争に参加できるはずです。 構文の一部がわからない場合は、公式仕様をいつでも参照できます。