# GraphQL Query の作成
GraphQL において、
データの取得・閲覧などの処理は Query
と呼ばれる形で定義されます。
まずは、サンプルで投入した 5件のタスク一覧を表示する、 タスク一覧の GraphQL Query を作成してみましょう。
# Query の定義
Laravel Lighthouse での GraphQL 定義は、
graphql/schema.graphql
に記述されます。
graphql/schema.graphql
にはすでに、 user 等の記述があるため、
以下のような GraphQL 定義を、 ファイルの末尾に追記しましょう。
extend type Query {
tasks: [Task!]! @all
}
type Task {
id: ID!
name: String!
priority: Int!
has_done: Boolean!
created_at: DateTime!
updated_at: DateTime!
}
Lighthouse で、Query の定義をする場合、 type Query
内にその定義を追加します。
今回は tasks
という名前の Query を追加し、:
の後ろで レスポンスの型 [Task!]!
を定義しています。
[Task!]!
は Task 型の配列を意味し !
は Null ではないことを表します。
レスポンスの型で利用した Task
型は、type Task{ ... }
の記述で定義し、
それぞれ、データベースの列項目を記述しています。
GraphQL の定義が整ったら、altair で以下のようなクエリを入力して リクエストを送信することで、タスクの一覧を取得することが出来ます。
TIP
Query
はすでにデフォルトで type Query
の記述がなされているため、
extend キーワードを用いて定義を拡張しています。
query{
tasks{
name
}
}
Lighthouse では、Eloquent クラスを App/Models
名前空間に展開することで、
型名と Eloquent クラスの自動マッピングが 行われます。
GraphQL 定義で利用した @all
は 該当するEloquent からすべてのデータを取得する機能を持つため、
これを利用して、タスク一覧の Query を作成することが出来ます。
# レスポンスのカスタマイズ
altair で発行するクエリを以下のように変更することで、 レスポンスに、 priority を 含めることが可能になります。
query{
tasks{
name
priority
}
}
priority だけでなく、 id も created_at も、 lighthouse の側の type で定義した項目は全て、クライアント側から取得可能になります。
逆に、updated_at などを クライアント側に表示したくない場合は、 lighthouse 側での type 定義から、以下のようにして updated_at を削除します。
type Task {
id: ID!
name: String!
priority: Int!
has_done: Boolean!
created_at: DateTime!
}
lighthouse の type 側で定義されていない項目は、 たとえ該当のデータベースにその列名があったとしても、 クライアント側でデータを取得することは出来ません。
updated_at を type の定義から削除したとき、 以下のようなクエリはエラーとなります。
query{
tasks{
name
priority
updated_at
}
}
# Query 処理のカスタマイズ
@all
のような、Lighthouse で提供されるディレクティブを利用すれば、
特別なコードを記述することなく、 Eloquent の機能を利用した Query 定義が可能になりますが、
実際のアプリケーション開発では、殆どの Query で何らかのロジックが必要になるでしょう。
Query の処理をコードベースで記述したい場合、
app/GraphQL/Queries
フォルダを作成して、Query クラスを定義します。
app/GraphQL/Queries/Tasks.php
を作成して以下のようなQuery クラスを作成してみましょう。
<?php
namespace App\GraphQL\Queries;
use App\Models\Task;
class Tasks
{
public function __invoke($rootValue, array $args)
{
$tasks = Task::orderBy("priority","DESC")->get();
return $tasks;
}
}
Query クラスのクラス名は、 GraphQL 側で定義したクエリ名と一致させます。
ここでは tasks
という名前で Query を定義しているため、クラス名は Tasks
となります。
クエリの処理は、 クラスの __invoke
関数内で定義します。
上記のコードでは、単純に task テーブルの全件を取得するのではなく、
priority
の列の値で、降順にソートした結果を返却するようコードを記述しています。
Query クラスの作成ができたら、
schema.graphql
の記述から以下のようにして @all
を削除します。
extend type Query {
tasks: [Task!]!
}
最後に、 altair で 以下のようなクエリを発行して、優先度で降順にソートされた結果が確認できるでしょう。
query{
tasks{
name
priority
}
}
# Check!
次のステップに進む前に以下の内容をもう一度確認しておきましょう。
@all
でQuery を定義して、 GraphQL からテーブルの内容を全件取得出来ますか?- 定義した Query を altair から発行する際に、項目名を選択して、レスポンスの内容を変化させることが出来ますか?
- PHP で定義した Query クラスの内容で、レスポンスのソート順や項目の数等を変化させることが出来ますか?