まくろぐ
更新:
作成:

インタフェース型を定義する

GraphQL のインタフェース型は、複数の型が共通して持つフィールドを定義するための抽象型で、interface キーワードを使って定義します。 次の ScheduleItem インタフェースは、2 つのフィールド(idtitle)を持つことを示しています。

スキーマ定義
# 共通のインタフェースを定義
interface ScheduleItem {
  id: ID!
  title: String!
}

インタフェースを実装する (imlements) 側の型は、必ず idtitle フィールドを持つ必要があります。 次の Task オブジェクト型と Milestone オブジェクト型は、ScheduleItem というインタフェースを実装しています。

スキーマ定義(続き)
# Task 型は必ず id と title フィールドを持つ
type Task implements ScheduleItem {
  id: ID!
  title: String!
  content: String
}

# Milestone 型は必ず id と title フィールドを持つ
type Milestone implements ScheduleItem {
  id: ID!
  title: String!
  date: DateTime
}

scalar DateTime

type Query {
  allItems(): [ScheduleItem!]
}

トップレベルの allItems クエリは、Task あるいは Milestone を要素とするリストを返すことを想定していますが、戻り値のリスト要素の型が ScheduleItem になっているため、必ず idtitle フィールドが含まれることが保証されています。

クエリでインタフェース型を使う

GraphQL クエリでインタフェース型のオブジェクトを返すフィールドを参照する場合、インタフェースで定義されたフィールドは、次のように直接参照することができます。

クエリ
query QueryAllItems {
  allItems {
    id
    title
  }
}

一方、Task 型や Milestone 型にしか含まれないフィールドを取得したいときは、次のように インラインフラグメント (... on Xxx) の形で分岐させて参照する必要があります。

クエリ
query QueryAllItems {
  allItems {
    id
    title
    ... on Task {
      content
    }
    ... on Milestone {
      date
    }
  }
}

複数のインタフェースを実装するオブジェクト型

あるオブジェクト型に複数のインタフェースを実装したいときは、次のように implements の後ろにインタフェース名を & で並べます。

"""
Represents a Milestone object on a given repository.
"""
type Milestone implements Closable & Node & UniformResourceLocatable {
  # ...
}

インタフェース型とユニオン型の使い分け

インタフェース型とユニオン型は、どちらも抽象型 (abstract types) を構成するための仕組みですが、両者は全く逆の意味を持っています。 インタフェース型が、複数の型が同じ振る舞い をすることを表現するのに対し、ユニオン型は、あるオブジェクトの実体が 異なる型になり得る ことを表現しています。

関連記事

まくろぐ
サイトマップまくへのメッセージ