# GraphQL Mutation の作成

GraphQL では、データの作成や更新・削除などの処理は Mutation と呼ばれる形で定義されます。

実際にクライアントからデータを追加できるような、GraphQL の Mutation を作成してみましょう。

# Query の定義

Mutation も Query と同様、graphql/schema.graphql に記述されます。

先程までの Query 定義や、 Task の type 定義はそのままに、 以下のような Mutation の GraphQL 定義を、ファイルの末尾に追記しましょう。

type Mutation {
    createTask(name: String!): Task! @create
}

Lighthouse で、Mutaion の定義をする場合、 type Mutaion 内にその定義を追加します。

今回は createTask という名前の Mutaion を追加し、: の後ろで レスポンスの型 Task! を定義しています。 Task! は 単一の Task 型のオブジェクトを意味します。

Mutation は多くの場合、Request パラメータを指定します。 GraphQL での Request パラメータは、Mutation 名の 後ろに () で記述します。 上記の例では、 パラメータ nameString 型で指定しています。

GraphQL の定義が整ったら、altair で以下のようなクエリを入力して リクエストを送信することで、新しいタスクをデータベースに追加することが出来ます。

mutation{
  createTask(name:"本を買う"){
    name
    priority
  }
}

Lighthosue では、 @create ディレクティブを利用して、 データベースの insert 処理を定義することが出来ます。

パラメータ名 name は 列名 name とマッピングされ、該当する列にパラメータの値が格納されます。

Mutation の定義を以下のように書き換えることで、 パラメータで priority の値も指定することができるようになります。

type Mutation {
    createTask(name: String!, priority: Int!): Task! @create
}

発行するクエリは以下のような例になります。


mutation{
  createTask(name: "宅配ボックスの確認", priority: 4){
    name
    priority
  }
}

# Mutation 処理のカスタマイズ

@create@all 同様、Lighthouse で提供されるディレクティブの機能になります。 実際のアプリケーション開発では、殆どの 格納処理で何らかのロジックが必要になるため、 クラスファイルを利用した Mutation の定義方法も確認しておきましょう。

Mutation の処理を記述する場合、 app/GraphQL/Mutations フォルダを作成して、Mutation クラスを定義します。 app/GraphQL/Mutations/CreateTask.php を作成して以下のような Mutation 処理を記述してみましょう。

<?php
namespace App\GraphQL\Mutations;

use App\Models\Task;

class CreateTask
{
    public function __invoke($rootValue, array $args)
    {
        $task = new Task();
        $task->name = "【{$args["name"]}】" ;
        $task->priority = $args["priority"];
        $task->save();

        $task->refresh();
        return $task;
    }
}

Mutation の処理も Query 同様、クラスの __invoke 関数内で定義します。 リクエストパラメータの値は __invoke 関数の $args 変数から取得可能です。

上記のコードでは、単純に task テーブルにデータを格納する際に、 入力された name パラメータを 【 】 で囲う処理をしています。 データベースへのデータ格納は Seeder で実施したのと同様、 new 演算子で作成したインスタンスに save をコールして実行できます。

has_done 列の値が、Databaseの default 値を用いて定義されるため、 default の値を取得しに、refresh 関数で Eloquent の値を最後に更新しています。

Mutation クラスを定義したら、 以下のような形で、クエリの定義から @createを削除します。

type Mutation {
    createTask(name: String!, priority: Int!): Task!
}

altair で 以下のようなクエリを発行することで、【】 で囲われた新しいタスクが、 データベースの task テーブルに格納されるでしょう。


mutation{
  createTask(name: "宅配ボックスの確認", priority: 4){
    name
    priority
  }
}

# Check!

次のステップに進む前に以下の内容をもう一度確認しておきましょう。

  • @create でQuery を定義して、 GraphQL からテーブルにデータを追加できますか?
  • 定義した Query を altair から発行して、altairで入力した内容が テーブルに反映されますか?
  • PHP で定義した Mutation クラスの内容で、データの作成処理を記述することが出来ますか?