Querier

GraphQLスキーマ完全ガイド | 理解して再利用できるスキーマ解説

2023.07.18に公開 | 2023.07.18に更新

Querier運営

@querier_io@querierinc

「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る

この記事では、近年話題のクエリ言語であるGraphQLのスキーマについて解説します。

これを読めば、GraphQLのスキーマについての全てが理解できるでしょう。それでは早速、見ていきましょう。

GraphQLスキーマとは

GraphQLスキーマは、GraphQL APIの型システムを定義したものです。

これは、APIで使用できるクエリと、そのクエリが何を返すかを明示的に示します。GraphQLスキーマは、特殊なスキーマ定義言語(SDL)で記述されます。

基本的なスキーマの型

Query, Mutation, Subscription

QueryはGraphQLの操作の一つで、データの読み取りを行います。クライアントからサーバーへの要求は主にQueryで行われ、サーバーからクライアントへのレスポンスはこのQueryに基づきます。

type Query {
  user(id: ID!): User
  users: [User]
}

Mutationはデータの変更を行います。

具体的には、データの作成(Create)、更新(Update)、削除(Delete)を行います。Mutationはサイドエフェクトを持つため、制御が重要です。

type Mutation {
  createUser(input: UserInput!): User
  updateUser(id: ID!, input: UserInput!): User
  deleteUser(id: ID!): User
}

Subscriptionはリアルタイムのデータの変更を購読します。サーバーからクライアントへのプッシュ型の通信であり、WebSocketを通じて実装されることが多いです。

type Subscription {
  userCreated: User
  userUpdated: User
  userDeleted: User
}

Scalar

Scalar型は、最小単位のデータ型を表します。GraphQLにはデフォルトで5つのScalar型が存在します。

IntFloatStringBooleanID。また、カスタムScalar型も作成することが可能です。

# 独自で定義したScalar型
scalar DateTime

type User {
  name: String
  age: Int
  weight: Float
  isAdmin: Boolean
  id: ID
  createdAt: DateTime
}

Object

Object型は、一連のフィールドを持つオブジェクトを表現します。これらのフィールドは他の型を持つことができ、そのため多くのGraphQLスキーマは多数のオブジェクト型から成り立ちます。

type User {
  id: ID
  name: String
  email: String
  friends: [User]
}

Enum

Enum型は特定の範囲の値のみを取りうるフィールドを定義します。これは一種の制約であり、それぞれの値は明示的に定義されます。

enum UserRole {
  ADMIN
  USER
  GUEST
}

type User {
  role: UserRole
}

List

List型は、特定の型の配列を定義します。List型は他の型(Scalar型やObject型など)を持つことができます。

type User {
  friends: [User]
}

Interface

Interface型は、共有フィールドを定義します。複数のオブジェクト型で共有するフィールドを一つにまとめることができます。それらのオブジェクト型はInterfaceを実装します。

interface LivingBeing {
  lifespan: Int
}

type Human implements LivingBeing {
  lifespan: Int
  occupation: String
}

type Dog implements LivingBeing {
  lifespan: Int
  breed: String
}

Union

Union型は、異なるオブジェクト型を1つのフィールドに結合します。これは共通フィールドを持たない異なる型をまとめる際に用いられます。

union SearchResult = User | Post

type Query {
  search(query: String!): [SearchResult]
}

Input

Input型は、複雑なオブジェクト型をクエリの引数として渡すために使用されます。これにより、一度に複数の引数を渡すことが可能になります。

input NewUserInput {
  name: String!
  email: String!
}

type Mutation {
  createUser(input: NewUserInput!): User
}

Scalar Extension

Scalar Extensionは、既存のScalar型を拡張します。これにより、既存の型に新たな振る舞いや機能を追加することができます。

extend scalar DateTime @directive

Nullability

NullはGraphQLにおいて、存在しない値や未定義の値を表す特殊な型です。GraphQLでは、フィールドがNull可能かどうかを明示的に指定することができます。

例えば、以下のようなUser型を考えます。

type User {
  name: String
  age: Int!
  address: String
}

この例では、nameフィールドはNull可能ですが、ageフィールドはNull不可能です。つまり、nameフィールドは存在しない場合にはNull値を返すことができますが、ageフィールドは必ず値が存在することが要求されます。

ディレクティブ

ディレクティブ(Directives)は、GraphQLスキーマにおいてフィールドやフラグメントなどの実行時の振る舞いを制御するための仕組みです。ディレクティブはスキーマ定義において使用され、クエリの実行時に評価されます。

ディレクティブは「@」記号を使ってフィールドやフラグメントに適用されます。ディレクティブはGraphQLの柔軟性を高め、クエリの実行時の制御やデータの変形を可能にします。

ディレクティブは以下のような構造を持ちます。

directive @directiveName(argument: ArgumentType) on DIRECTIVE_LOCATION
  • directiveNameはディレクティブの名前です。
  • argumentはディレクティブに渡される引数です。引数はディレクティブが実行される際に評価されます。
  • DIRECTIVE_LOCATIONはディレクティブが適用できる場所を示します。例えば、フィールド、フラグメントスプレッド、インラインフラグメントなどです。

代表的なディレクティブ

@include / @skip

@includeディレクティブと@skipディレクティブは、条件に基づいてフィールドを含めるかスキップするために使用されます。

query GetUser($includeAddress: Boolean!) {
  user {
    name
    age
    address @include(if: $includeAddress)
  }
}

上記の例では、クエリ変数includeAddressの値に応じて、addressフィールドが含まれるかスキップされるかが決まります。

@deprecated

@deprecatedディレクティブは、古いフィールドやタイプをマークするために使用されます。これにより、クライアントに対して非推奨であることを示すことができます。

type User {
  email: String @deprecated(reason: "Use 'contact' field instead.")
  contact: String
}

上記の例では、emailフィールドが非推奨であり、代わりにcontactフィールドを使用するように推奨されます。

@auth

@authディレクティブは、認証と認可を制御するために使用されます。クエリの実行前にユーザーの認証状態や権限を検証し、必要な権限があるかどうかを確認することができます。

type Query {
  sensitiveData @auth(roles: ["admin"])
}

上記の例では、sensitiveDataフィールドにアクセスするためには、adminロールの権限が必要です。それ以外のユーザーはアクセスできません。

@cacheControl

@cacheControlディレクティブは、クエリの結果をキャッシュするためのキャッシュコントロールのヒントを提供します。

type Query {
  expensiveOperation: Result @cacheControl(maxAge: 3600)
}

上記の例では、expensiveOperationフィールドの結果を1時間キャッシュすることが示されています。

これらは一部の代表的なディレクティブの例ですが、カスタムディレクティブも作成することができます。ディレクティブを使用することで、クエリの制御やデータの変形を柔軟に行うことができます。

さいごに

この記事では、GraphQLのスキーマについて詳しく解説しました。GraphQLスキーマはAPIの型システムを定義し、データの取得や変更の操作方法を明示します。さらに、ディレクティブについても解説しました。ディレクティブはクエリの実行時の振る舞いを制御し、柔軟性と再利用性を向上させます。

GraphQLのスキーマとディレクティブについて理解することで、APIの設計や開発を効率化し、柔軟性のあるデータフェッチを実現することができます。

引き続き、GraphQLの学習と実践を進め、その可能性を最大限に引き出してください。

「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

最新の記事

2〜3ヶ月と見積もっていた開発期間を、クエリアを導入することでわずか1週間に短縮できました

2012年5月創業のフルカイテン株式会社。 「在庫をフル回転させる」をコンセプトに、機械学習を駆使したSaaS『FULL KAITEN』を提供し、在庫問題の解決に取り組む。

more

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る