Laravelを使用したGraphQLサーバーの構築
公開: 2022-03-11まだ慣れていない場合は、GraphQLはAPIとの対話に使用されるクエリ言語であり、RESTなどの代替アーキテクチャと比較していくつかの利点があります。 GraphQLは、モバイルおよびシングルページアプリケーションのエンドポイントとして使用する場合に非常に便利です。 GraphQLを使用すると、リクエスト内のネストされた関連データを比較的簡単にクエリできるため、開発者はサーバーへの1回のラウンドトリップで必要な正確なデータを取得できます。
Laravelは、人気のある、意見の分かれるPHPWebフレームワークです。 アプリケーションをすばやく起動して実行するための多数の組み込みツールを提供しますが、開発者は、必要に応じて、独自の実装をLaravelの組み込みインターフェースに交換することもできます。
GraphQLとLaravelの両方を取り巻くコミュニティは、オープンソース化されてから劇的に成長しましたが、これら2つのテクノロジーを一緒に使用する方法を説明するドキュメントはまだやや不足しています。
そのため、このチュートリアルでは、Laravelを使用して独自のGraphQLサーバーを作成する方法を紹介します。
プロジェクトの概要
始める前に、構築しようとしているプロジェクトに精通する必要があります。 そのために、リソースを定義し、GraphQLスキーマを作成します。このスキーマは、後でAPIを提供するために使用します。
プロジェクトリソース
このアプリケーションは、 ArticlesとUsersの2つのリソースで構成されます。 これらのリソースは、GraphQLスキーマでオブジェクトタイプとして定義されます。
type User { id: ID! name: String! email: String! articles: [Article!]! } type Article { id: ID! title: String! content: String! author: User! }
スキーマを見ると、2つのオブジェクト間に1対多の関係があることがわかります。 ユーザーは多くの記事を書くことができ、記事には著者(ユーザー)が割り当てられます。
オブジェクトタイプを定義したので、データを作成してクエリする方法が必要になるので、クエリオブジェクトとミューテーションオブジェクトを定義しましょう。
type Query { user(id: ID!): User users: [User!]! article(id: ID!): Article articles: [Article!]! } type Mutation { createUser(name: String!, email: String!, password: String!): User createArticle(title: String!, content: String!): Article }
Laravelプロジェクトの設定
GraphQLスキーマを定義したので、Laravelプロジェクトを稼働させましょう。 Composerプロジェクトを介して新しいLaravelを作成することから始めましょう:
$ composer create-project --prefer-dist laravel/laravel laravel-graphql
すべてが機能していることを確認するために、サーバーを起動して、Laravelのデフォルトページが表示されていることを確認しましょう。
$ cd laravel-graphql $ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
データベースモデルと移行
この記事では、SQLiteを使用します。 それでは、デフォルトの.env
ファイルに次の変更を加えましょう。
DB_CONNECTION=sqlite # DB_HOST= # DB_PORT= # DB_DATABASE=database.sqlite # DB_USERNAME= # DB_PASSWORD=
次に、データベースファイルを作成しましょう。
$ touch ./database/database.sqlite
Laravelには、ユーザーモデルといくつかの基本的な移行ファイルが付属しています。 Laravelから提供されたCreateUsersTable
移行ファイルのapi_token
列をすばやく追加しましょう。
/database/migrations/XXXX_XX_XX_000000_create_users_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. */ public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('api_token', 80)->unique()->nullable()->default(null); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down() { Schema::dropIfExists('users'); } }
承認が得られたら、この記事の後半でこの追加の列に戻ります。 次に、記事モデルと移行ファイルを作成して、関連するテーブルを作成しましょう。
$ php artisan make:model Article -m
注: -mオプションは、新しく作成された記事モデルの移行ファイルを作成します。
生成された移行ファイルにいくつかの調整を加えましょう。
use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticlesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('user_id'); $table->string('title'); $table->text('content'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }
users
テーブルのid
と、GraphQLスキーマで定義したtitle
列とcontent
列を指す外部キーを追加しました。
移行ファイルが定義されたので、先に進んでデータベースに対して実行します。
$ php artisan migrate
次に、必要な関係を定義してモデルを更新しましょう。
app/User.php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; // ... /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function articles() { return $this->hasMany(Article::class); } }
app/Article.php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'title', 'content', ]; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class); } }
データベースシード
モデルと移行の設定が完了したので、データベースにシードを設定しましょう。 まず、 articles
とusers
テーブルのシーダークラスをいくつか作成します。
$ php artisan make:seeder UsersTableSeeder $ php artisan make:seeder ArticlesTableSeeder
次に、SQLiteデータベースにダミーデータを挿入するように設定しましょう。
database/seeds/UsersTableSeeder.php use App\User; use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\User::truncate(); $faker = \Faker\Factory::create(); $password = bcrypt('secret'); \App\User::create([ 'name' => $faker->name, 'email' => '[email protected]', 'password' => $password, ]); for ($i = 0; $i < 10; ++$i) { \App\User::create([ 'name' => $faker->name, 'email' => $faker->email, 'password' => $password, ]); } } }
database/seeds/ArticlesTableSeeder.php use App\Article; use Illuminate\Database\Seeder; class ArticlesTableSeeder extends Seeder { /** * Run the database seeds. */ public function run() { \App\Article::truncate(); \App\Article::unguard(); $faker = \Faker\Factory::create(); \App\User::all()->each(function ($user) use ($faker) { foreach (range(1, 5) as $i) { \App\Article::create([ 'user_id' => $user->id, 'title' => $faker->sentence, 'content' => $faker->paragraphs(3, true), ]); } }); } }
/database/seeds/DatabaseSeeder.php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); $this->call(ArticlesTableSeeder::class); } }
最後に、データベースシーダーを実行して、データベースにデータを取得しましょう。
$ php artisan db:seed
Laravel灯台とGraphQLサーバー
データベースとモデルのセットアップが完了したので、GraphQLサーバーの構築を開始します。 現在、Laravelで利用できるソリューションはいくつかありますが、この記事ではLighthouseを使用します。
灯台は私が数年前に作成したパッケージであり、最近、その周りの成長するコミュニティからいくつかの驚くべきサポートが見られました。 これにより、開発者は、ボイラープレートがほとんどないLaravelを使用してGraphQLサーバーをすばやくセットアップできると同時に、開発者がほぼすべてのプロジェクトのニーズに合わせてカスタマイズできるように十分な柔軟性を備えています。
パッケージをプロジェクトに取り込むことから始めましょう。
$ composer require nuwave/lighthouse:"3.1.*"
次に、Lighthouseの構成ファイルを公開しましょう。
$ php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider" --tag=config
注: --tag=config
オプションを削除するだけで、Lighthouseのデフォルトスキーマファイルを公開することもできます。 ただし、この記事では、スキーマファイルを最初から作成します。
config/lighthouse.php
ファイルを見ると、スキーマファイルをLighthouseに登録するために使用される設定に気付くでしょう。
'schema' => [ 'register' => base_path('graphql/schema.graphql'), ],
それでは、先に進んでスキーマファイルを作成し、ユーザーオブジェクトタイプとクエリを設定しましょう。
$ mkdir graphql $ touch ./graphql/schema.graphql /graphql/schema.graphql type User { id: ID! name: String! email: String! } type Query { user(id: ID! @eq): User @find users: [User!]! @all }
スキーマディレクティブと呼ばれる識別子をいくつか追加したことを除けば、スキーマは前に定義したものと似ていることに気付くでしょう。
定義されたスキーマを分解してみましょう。 最初の定義は、 App\User
の雄弁なモデルと関係のあるUser
というオブジェクトタイプです。 id
、 name
、 email
を、 User
モデルからクエリできるフィールドとして定義しました。 または、これは、 password
、 created_at
、 updated_at
列が、APIから照会できないフィールドであることを意味します。
次に、APIへのエントリポイントであり、データのクエリに使用できるQuery
タイプがあります。 最初のフィールドは、 User
オブジェクトタイプの配列を返すusers
フィールドです。 @all
ディレクティブは、 User
モデルを使用してEloquentクエリを実行し、すべての結果を取得するようにLighthouseに指示します。 これは、以下を実行するのと同じです。
$users = \App\User::all();
注: Lighthouseは、構成ファイルで定義されているnamespaces
オプションがあるため、 \App\User
名前空間でモデルを探すことを認識しています。
クエリタイプで2番目に定義されたフィールドは、呼び出しuser
です。これは、引数としてid
を受け取り、単一のUser
オブジェクトタイプを返します。 また、Lighthouseが自動的にクエリを作成し、単一のUser
モデルを返すのに役立つ2つのディレクティブを追加しました。 @eq
ディレクティブはLighthouseにid
列にwhereを追加するように指示し、 @find
ディレクティブはLighthouseに単一の結果を返すように指示します。 Laravelのクエリビルダーを使用してこのクエリを作成するには、次のようになります。
$user = \App\User::where('id', $args['id'])->first();
GraphQLAPIのクエリ
Lighthouseがスキーマを使用してクエリを作成する方法について少し洞察したので、サーバーを実行してデータのクエリを開始しましょう。 サーバーを実行することから始めます。
$ php artisan serve Laravel development server started: <http://127.0.0.1:8000>
GraphQLエンドポイントをクエリするには、ターミナルまたはPostmanなどの標準クライアントでcURLコマンドを実行できます。 ただし、GraphQLのすべての利点(オートコンプリート、エラーの強調表示、ドキュメントなど)を取得するには、GraphQL Playgroundを使用します(ここからダウンロードをリリースします)。
Playgroundを起動するときは、[URLエンドポイント]タブをクリックし、http:// localhost:8000/graphqlと入力してGraphQLPlaygroundをサーバーにポイントします。 エディターの左側で、データを照会できるので、データベースにシードしたすべてのユーザーを尋ねることから始めましょう。
{ users { id email name } }
IDEの中央にある再生ボタンを押すと(またはCtrl + Enterをクリックすると)、右側にサーバーのJSON出力が表示されます。これは次のようになります。
{ "data": { "users": [ { "id": "1", "email": "[email protected]", "name": "Carolyn Powlowski" }, { "id": "2", "email": "[email protected]", "name": "Elouise Raynor" }, { "id": "3", "email": "[email protected]", "name": "Mrs. Dejah Wiza" }, ... ] } }
注:データベースのシードにFakerを使用したため、 email
フィールドとname
フィールドのデータは異なります。
それでは、シングルユーザーのクエリを試してみましょう。
{ user(id: 1) { email name } }
また、1人のユーザーに対して次の出力が得られます。
{ "data": { "user": { "email": "[email protected]", "name": "Carolyn Powlowski" } } }
このようなデータのクエリを開始するのは良いことですが、すべてのデータをクエリしたいプロジェクトに参加する可能性は非常に低いので、ページネーションを追加してみましょう。 Lighthouseのさまざまな組み込みディレクティブを調べると、 @paginate
ディレクティブをすぐに利用できるので、次のようにスキーマのクエリオブジェクトを更新しましょう。
type Query { user(id: ID! @eq): User @find users: [User!]! @paginate }
GraphQL Playground( Ctrl / Cmd + R )をリロードしてusers
クエリを再試行するとCannot query field "id" on type "UserPaginator"
というエラーメッセージが表示されるので、どうなりましたか? 舞台裏では、Lighthouseはスキーマを操作して、ページ化された一連の結果を取得し、 users
フィールドの戻り値のタイプを変更します。
GraphQL Playgroundの[Docs]タブでスキーマを調べて、詳しく見てみましょう。 users
フィールドを見ると、ユーザーの配列とLighthouseで定義されたPaginatorInfo
タイプを返すUserPaginator
が返されています。

type UserPaginator { paginatorInfo: PaginatorInfo! data: [User!]! } type PaginatorInfo { count: Int! currentPage: Int! firstItem: Int hasMorePages: Boolean! lastItem: Int lastPage: Int! perPage: Int! total: Int! }
Laravelの組み込みのページ付けに精通している場合、 PaginatorInfo
タイプで使用可能なフィールドはおそらく非常に馴染みのあるものになります。 したがって、2人のユーザーを照会し、システム内のユーザーの総数を取得し、循環するページがまだあることを確認するには、次の照会を送信します。
{ users(count:2) { paginatorInfo { total hasMorePages } data { id name email } } }
これにより、次の応答が得られます。
{ "data": { "users": { "paginatorInfo": { "total": 11, "hasMorePages": true }, "data": [ { "id": "1", "name": "Carolyn Powlowski", "email": "[email protected]" }, { "id": "2", "name": "Elouise Raynor", "email": "[email protected]" }, ] } } }
関係
一般に、アプリケーションを開発するとき、データの多くは関連しています。 この場合、 User
は多くのArticles
を書くことができるので、その関係をユーザータイプに追加し、 Article
タイプを定義しましょう。
type User { id: ID! name: String! email: String! articles: [Article!]! @hasMany } type Article { id: ID! title: String! content: String! }
ここでは、Lighthouseが提供する別のスキーマディレクティブ@hasMany
を使用しています。これは、LighthouseにUser
モデルがArticle
モデルと\Illuminate\Database\Eloquent\Relations\HasMany
関係にあることを通知します。
次に、新しく定義した関係を照会してみましょう。
{ user(id:1) { articles { id title } } }
これにより、次の応答が返されます。
{ "data": { "user": { "articles": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint." }, { "id": "2", "title": "Voluptatem sed labore ea voluptas." }, { "id": "3", "title": "Beatae sit et maxime consequatur et natus totam." }, { "id": "4", "title": "Corrupti beatae cumque accusamus." }, { "id": "5", "title": "Aperiam quidem sit esse rem sed cupiditate." } ] } } }
最後に、関係を逆にして、Lighthouseの@belongsTo
スキーマディレクティブを使用し、 Query
を更新して、 Article
オブジェクトタイプに作成author
の関係を追加しましょう。
type Article { id: ID! title: String! content: String! author: User! @belongsTo(relation: "user") } type Query { user(id: ID! @eq): User @find users: [User!]! @paginate article(id: ID! @eq): Article @find articles: [Article!]! @paginate }
@belongsTo
ディレクティブにオプションのrelation
引数を追加したことがわかります。 これにより、LighthouseはArticles
モデルのuser
関係を使用し、それを作成author
フィールドに割り当てるように指示されます。
次に、記事のリストを照会して、関連する著者を取得しましょう。
{ articles(count:2) { paginatorInfo { total hasMorePages } data { id title author { name email } } } }
そして、サーバーから次のものを取得する必要があります。
{ "data": { "articles": { "paginatorInfo": { "total": 55, "hasMorePages": true }, "data": [ { "id": "1", "title": "Aut velit et temporibus ut et tempora sint.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } }, { "id": "2", "title": "Voluptatem sed labore ea voluptas.", "author": { "name": "Carolyn Powlowski", "email": "[email protected]" } } ] } } }
GraphQLミューテーション
データをクエリできるようになったので、いくつかのミューテーションを作成して、新しいユーザーと記事を作成しましょう。 まず、ユーザーモデルから始めます。
type Mutation { createUser( name: String! email: String! @rules(apply: ["email", "unique:users"]) password: String! @bcrypt @rules(apply: ["min:6"]) ): User @create }
それでは、このスキーマ定義を分解してみましょう。 3つの引数( name
、 email
、 password
)をとるcreateUser
というミューテーションを作成しました。 email
とpassword
の両方の引数に@rules
ディレクティブを適用しました。 これは、Laravelがコントローラーに提供する検証ロジックに似ているため、少し見覚えがあるかもしれません。
次に、 @bcrypt
ディレクティブをpassword
フィールドに添付しました。 これにより、パスワードは新しく作成されたモデルに渡される前に暗号化されます。
最後に、新しいモデルの作成を支援するために、Lighthouseは、定義した引数を取得して新しいモデルを作成する@create
スキーマディレクティブを提供します。 コントローラで同じロジックを実行すると、次のようになります。
namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Create a new user. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $data = $this->validate($request, [ 'email' => ['email', 'unique:users'], 'password' => ['min:6'] ]); $user = \App\User::create($data); return response()->json(['user' => $user]); } }
createUserミューテーションフィールドが設定されたので、先に進んで、次のようにGraphQLPlaygroundで実行します。
mutation { createUser( name:"John Doe" email:"[email protected]" password: "secret" ) { id name email } }
次の出力が得られるはずです。
{ "data": { "createUser": { "id": "12", "name": "John Doe", "email": "[email protected]" } } }
GraphQLの認証と承認
Article
モデルにuser_id
を追加する必要があるため、GraphQL/Lighthouseでの認証と承認を確認する絶好の機会です。
ユーザーを認証するには、 api_token
をユーザーに提供する必要があるため、それを処理するミューテーションを作成し、ロジックを処理するカスタムリゾルバーをLighthouseにポイントする@field
ディレクティブを追加します。 resolver
引数を使用してLaravelでコントローラーを定義するのと同じパターンでリゾルバーを設定します。
以下に定義されている@field
ディレクティブを使用して、 login
ミューテーションが実行されたときにLighthouseに通知しますApp\GraphQL\Mutations\AuthMutator
クラスでcreateToken
メソッドを使用します。
type Mutation { # ... login( email: String! password: String! ): String @field(resolver: "AuthMutator@resolve") }
注:ここに名前空間全体を含める必要はありません。 lighthouse.php
構成ファイルでは、ミューテーション用に定義された名前空間がすでにApp\\GraphQL\\Mutations
として設定されていることがわかりますが、必要に応じて完全な名前空間を使用できます。
Lighthouseのジェネレーターを使用して、新しいミューテータークラスを作成しましょう。
$ php artisan lighthouse:mutation AuthMutator
次に、次のようにリゾルバー関数を更新しましょう。
namespace App\GraphQL\Mutations; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Facades\Auth; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class AuthMutator { /** * Return a value for the field. * * @param null $rootValue Usually contains the result returned from the parent field. In this case, it is always `null`. * @param mixed[] $args The arguments that were passed into the field. * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context Arbitrary data that is shared between all fields of a single query. * @param \GraphQL\Type\Definition\ResolveInfo $resolveInfo Information about the query itself, such as the execution state, the field name, path to the field from the root, and more. * @return mixed */ public function resolve($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) { $credentials = Arr::only($args, ['email', 'password']); if (Auth::once($credentials)) { $token = Str::random(60); $user = auth()->user(); $user->api_token = $token; $user->save(); return $token; } return null; } }
リゾルバーがセットアップされたので、それをテストして、GraphQLPlaygroundで次のミューテーションを使用してAPIトークンを取得してみましょう。
mutation { login(email:"[email protected]", password:"secret") }
次のようにトークンを返送する必要があります。
{ "data": { "login": "VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" } }
注:後で使用できるように、ログインミューテーションから返されたトークンを必ずコピーしてください。
次に、認証されたユーザーを返すクエリフィールドを追加して、ロジックが機能することを確認します。 me
というフィールドを追加し、Lighthouseの@auth
ディレクティブを使用して、現在認証されているユーザーを返します。 また、 guard
引数をapi
に設定します。これは、ユーザーを認証する方法だからです。
type Query { # ... me: User @auth(guard: "api") }
それでは、クエリを実行してみましょう。 GraphQL Playgroundでは、下部にある[HttpHeaders]タブをダブルクリックしてリクエストヘッダーを設定できます。 JSONオブジェクトを使用してヘッダーを追加するため、各リクエストにベアラートークンを追加するには、次を追加します。
{ "Authorization": "Bearer VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE" }
注:ベアラートークンを、ログインクエリの実行時に受け取ったトークンに置き換えます。
それでは、 me
クエリを実行してみましょう。
{ me { email articles { id title } } }
次のような出力が得られるはずです。
{ "data": { "me": { "email": "[email protected]", "articles": [ { "id": "1", "title": "Rerum perspiciatis et quos occaecati exercitationem." }, { "id": "2", "title": "Placeat quia cumque laudantium optio voluptatem sed qui." }, { "id": "3", "title": "Optio voluptatem et itaque sit animi." }, { "id": "4", "title": "Excepturi in ad qui dolor ad perspiciatis adipisci." }, { "id": "5", "title": "Qui nemo blanditiis sed fugit consequatur." } ] } } }
ミドルウェア
認証が正しく機能していることがわかったので、最後のミューテーションを作成して、現在認証されているユーザーを使用して記事を作成しましょう。 @field
ディレクティブを使用してLighthouseをリゾルバーにポイントし、@ @middleware
ディレクティブを含めてユーザーが確実にログインできるようにします。
type Mutation { # ... createArticle(title: String!, content: String!): Article @field(resolver: "ArticleMutator@create") @middleware(checks: ["auth:api"]) }
まず、ミューテーションクラスを生成しましょう。
$ php artisan lighthouse:mutation ArticleMutator
次に、ミューテータを次のロジックで更新しましょう。
namespace App\GraphQL\Mutations; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class ArticleMutator { /** * Return a value for the field. * * @param null $rootValue * @param mixed[] $args * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context * @return mixed */ public function create($rootValue, array $args, GraphQLContext $context) { $article = new \App\Article($args); $context->user()->articles()->save($article); return $article; } }
注:デフォルトのresolve
関数の名前を「 create
」に変更しました。 リゾルバーごとに新しいクラスを作成する必要はありません。 代わりに、より理にかなっている場合は、ロジックをグループ化できます。
最後に、新しいミューテーションを実行して、出力を確認しましょう。 [HTTPヘッダー]タブの前のクエリのAuthorization
ヘッダーを必ず保持してください。
mutation { createArticle( title:"Building a GraphQL Server with Laravel" content:"In case you're not currently familiar with it, GraphQL is a query language used to interact with your API..." ) { id author { id email } } }
次の出力が得られるはずです。
{ "data": { "createArticle": { "id": "56", "author": { "id": "1", "email": "[email protected]" } } } }
まとめ
要約すると、Lighthouseを利用してLaravelプロジェクト用のGraphQLサーバーを作成しました。 いくつかの組み込みスキーマディレクティブを利用し、クエリとミューテーションを作成し、承認と認証を処理しました。
Lighthouseを使用すると、さらに多くのことができます(独自のカスタムスキーマディレクティブを作成できるようにするなど)が、この記事の目的のために、基本に固執し、わずかな定型文でGraphQLサーバーを稼働させることができました。
次回、モバイルまたはシングルページアプリケーション用のAPIを設定する必要がある場合は、データをクエリする方法としてGraphQLを検討してください。