フィールド
GraphQL APIのエントリーポイントは、ルートタイプである Query
, Mutation
, Subscription
のフィールドです。
すべての フィールドには関数が関連付けられており、クエリの一部としてフィールドが要求されたときに呼び出されます。 この関数は resolver と呼ばれます。
Hello World
このセクションでは伝統に従って、Lighthouseで"Hello World!"を出力する方法を学びます。
まず、最もシンプルなスキーマを定義することから始めます。ルートであるQuery
タイプにhello
というフィールドを一つ追加しString
を返します。
これはデータの形式を定義し、クライアントに対してどんなクエリを期待できるかを示します。 次に、実際のリゾルバを実装する必要があります。
デフォルトでは、Lighthouseはフィールド名がの先頭が大文字になっているクラスをApp\GraphQL\Queries
またはApp\GraphQL\Mutations
から探し、そのクラスの__invoke
関数を通常のリゾルバの引数で呼びます。
今回の場合、フィールドはクエリーでhello
という名前なので、以下のようにクラスを定義する必要があります。
<?php
namespace App\GraphQL\Queries;
class Hello
{
public function __invoke(): string
{
return 'world!';
}
}
このようなクラスを作成する最も簡単な方法は、Lighthouseが用意しているartisan
コマンドであるlighthouse:query
とlighthouse:mutation
を使用することです。どちらも引数を1つ取ります。
引数の内容は生成したいフィールドの名前です。
例えば、hello
というフィールドのクラスを生成するには、以下のようにします。
php artisan lighthouse:query Hello
これで定義したスキーマのクエリを実行できるようになりました。
このクエリは以下のレスポンスを返します:
引数を持つフィールド
これまで学んだように、全ての フィールドにはリゾルバ関数が関連付けられています。 関数と同じようにフィールドも引数を取ってその振る舞いを制御することができます。
ユーザーに挨拶するクエリを作ってみましょう。挨拶のメッセージを作成するのに使用する、必須の引数 name
を追加します。
このフィールドの最小限の実装は、以下のようになります。
このクラスの雛形はphp artisan lighthouse:query Greet
で作成できます。
リゾルバ関数の第2引数は、クエリに渡される引数の連想配列です。
<?php
namespace App\GraphQL\Queries;
class Greet
{
public function __invoke($rootValue, array $args): string
{
return "Hello, {$args['name']}!";
}
}
このクエリを任意のname
を渡して呼び出すことができます。
すると、よりフレンドリーな挨拶メッセージが受け取れます。
もしユーザーに引数を渡したくない場合は、スキーマを修正してname
を任意の引数にし、デフォルト値を指定します。
これによって、以下のようにクエリを使用できます。
非ルートなフィールドのリゾルバ
前述のとおり、スキーマのすべてのフィールドにはリゾルバがあります。 しかし、ルート型に属さないフィールドはどうでしょうか?
さて、クライアントが以下のクエリを送信したときに何が起こるかを見てみましょう:
まず、user
のリゾルバが呼び出されます。ここでは、AppModelUser
のインスタンスすると仮定します。
次に、フィールドのサブセレクションが解決されます。ここで、リクエストされたフィールドはid
とname
の2つです。
親フィールドであるUserはすでに解決しているので、その属性を取得するために再度取得する必要はありません。
便利なことに、各リゾルバの最初の引数は親のフィールドが渡されます。この場合はUserモデルです。
'id`に対するリゾルバのシンプルな実装は、以下のようになります。
このようなリゾルバをひとつひとつ書いていくのは、かなり冗長になります。
4番目のリゾルバの引数であるResolveInfo
を使用することで、リクエストされたフィールド名にアクセスし、一致するプロパティに動的にアクセスできます。
<?php
use App\Models\User;
use GraphQL\Type\Definition\ResolveInfo;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
function resolveUserAttribute(User $user, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
{
return $user->{$resolveInfo->fieldName};
}
幸いなことに、基礎となるGraphQL実装はすでに賢明なデフォルトリゾルバを提供しており、Eloquent
モデルや連想配列といったルートリゾルバから返されるデータとうまく連携しています。
これが意味するところは、ほとんどの場合においてはルートフィールド用のリゾルバを用意し、それが適切な形のデータを返すようにするだけでよいということです。
もし、ルートタイプQuery
やMutation
以外のフィールドにカスタムリゾルバを実装する必要がある場合には、@field、または@methodディレクティブを使用できます。
必要であればデフォルトのリゾルバの変更も可能です。