Implementing Basic Mutations to Create, Update, and Delete Data in Laravel GraphQL


GraphQL provides a flexible approach to API design, allowing clients to query exactly the data they need. However, it's not just about reading data—GraphQL mutations allow you to modify data by creating, updating, and deleting records in your database. In this article, we'll walk through implementing basic mutations using Laravel and the Rebing GraphQL package to handle these operations.


Prerequisites


Before we begin, ensure you have:


1. A Laravel project installed. If you don't have one, create a new Laravel project:

   composer create-project --prefer-dist laravel/laravel graphql-demo


2. The Rebing GraphQL package installed in your Laravel project:

   composer require rebing/graphql-laravel


3. Basic knowledge of Laravel Eloquent models.


Step 1: Setting Up Your GraphQL Schema


To handle mutations in Laravel GraphQL, we will first create a schema. This includes types and mutations to define what data the client can manipulate.


Create a User Type


First, let's define a UserType for a user entity in your application. This type represents the structure of a user in your GraphQL schema. Create a file `UserType.php` in the `app/GraphQL/Types/` directory:


namespace App\GraphQL\Types;


use Rebing\GraphQL\Support\Type as GraphQLType;

use GraphQL\Type\Definition\Type;


class UserType extends GraphQLType

{

    protected $attributes = [

        'name' => 'User',

        'description' => 'A type that describes a user',

    ];


    public function fields(): array

    {

        return [

            'id' => [

                'type' => Type::nonNull(Type::int()),

                'description' => 'The ID of the user',

            ],

            'name' => [

                'type' => Type::string(),

                'description' => 'The name of the user',

            ],

            'email' => [

                'type' => Type::string(),

                'description' => 'The email of the user',

            ],

        ];

    }

}


This defines the fields that can be queried or returned for a user, such as `id`, `name`, and `email`.


Step 2: Implementing the Create Mutation


A mutation in GraphQL allows clients to modify data. In this case, we'll define a mutation to create a new user. Create a `CreateUserMutation.php` file in the `app/GraphQL/Mutations/` directory:


namespace App\GraphQL\Mutations;


use Rebing\GraphQL\Support\Mutation;

use GraphQL\Type\Definition\Type;

use App\Models\User;


class CreateUserMutation extends Mutation

{

    protected $attributes = [

        'name' => 'createUser'

    ];


    public function type(): Type

    {

        return \GraphQL::type('User');

    }


    public function args(): array

    {

        return [

            'name' => [

                'type' => Type::nonNull(Type::string()),

                'description' => 'The name of the user',

            ],

            'email' => [

                'type' => Type::nonNull(Type::string()),

                'description' => 'The email of the user',

            ],

        ];

    }


    public function resolve($root, $args)

    {

        return User::create([

            'name' => $args['name'],

            'email' => $args['email'],

        ]);

    }

}


This mutation accepts `name` and `email` as inputs and creates a new user in the database.


Step 3: Implementing the Update Mutation


Next, we'll add a mutation to update an existing user. Create an `UpdateUserMutation.php` file:


namespace App\GraphQL\Mutations;


use Rebing\GraphQL\Support\Mutation;

use GraphQL\Type\Definition\Type;

use App\Models\User;


class UpdateUserMutation extends Mutation

{

    protected $attributes = [

        'name' => 'updateUser'

    ];


    public function type(): Type

    {

        return \GraphQL::type('User');

    }


    public function args(): array

    {

        return [

            'id' => [

                'type' => Type::nonNull(Type::int()),

                'description' => 'The ID of the user to update',

            ],

            'name' => [

                'type' => Type::string(),

                'description' => 'The new name of the user',

            ],

            'email' => [

                'type' => Type::string(),

                'description' => 'The new email of the user',

            ],

        ];

    }


    public function resolve($root, $args)

    {

        $user = User::find($args['id']);

        if (!$user) {

            return null;

        }


        $user->name = $args['name'] ?? $user->name;

        $user->email = $args['email'] ?? $user->email;

        $user->save();


        return $user;

    }

}


This mutation updates the `name` and `email` fields for an existing user based on the provided `id`.


Step 4: Implementing the Delete Mutation


Finally, let's create a mutation to delete a user. Create a `DeleteUserMutation.php` file:


namespace App\GraphQL\Mutations;


use Rebing\GraphQL\Support\Mutation;

use GraphQL\Type\Definition\Type;

use App\Models\User;


class DeleteUserMutation extends Mutation

{

    protected $attributes = [

        'name' => 'deleteUser'

    ];


    public function type(): Type

    {

        return Type::boolean(); // Return a boolean indicating success or failure

    }


    public function args(): array

    {

        return [

            'id' => [

                'type' => Type::nonNull(Type::int()),

                'description' => 'The ID of the user to delete',

            ],

        ];

    }


    public function resolve($root, $args)

    {

        $user = User::find($args['id']);

        if (!$user) {

            return false;

        }


        return $user->delete() ? true : false;

    }

}


This mutation deletes a user by their ID and returns a boolean to indicate whether the operation was successful.


Step 5: Registering the Mutations in the Schema


Now that the mutations are created, we need to register them in the GraphQL schema. Open `config/graphql.php` and add your mutations:


return [

    'schema' => [

        'default' => [

            'query' => [

                // Add any queries here...

            ],

            'mutation' => [

                'createUser' => App\GraphQL\Mutations\CreateUserMutation::class,

                'updateUser' => App\GraphQL\Mutations\UpdateUserMutation::class,

                'deleteUser' => App\GraphQL\Mutations\DeleteUserMutation::class,

            ],

        ],

    ],

    'types' => [

        'User' => App\GraphQL\Types\UserType::class,

    ],

];


This config file now includes all the necessary mutations (`createUser`, `updateUser`, `deleteUser`) and the `UserType`.


Step 6: Testing Your GraphQL Mutations


To test your mutations, you can use API clients like Postman, Insomnia, or GraphiQL.


Example Create Mutation Request


mutation {

  createUser(name: "John Doe", email: "john@example.com") {

    id

    name

    email

  }

}


Example Update Mutation Request


mutation {

  updateUser(id: 1, name: "Jane Doe", email: "jane@example.com") {

    id

    name

    email

  }

}


Example Delete Mutation Request


mutation {

  deleteUser(id: 1)

}


After sending these requests, you should see the expected responses from your GraphQL API.


Implementing mutations in Laravel GraphQL allows you to perform data modification operations like creating, updating, and deleting records. By defining these mutations in combination with Eloquent models, you can build powerful and flexible APIs for your applications. With the Rebing GraphQL package, Laravel makes it easy to integrate GraphQL functionality and streamline your API development. 


As you progress, consider adding more complex logic, such as validation, authorization, and handling nested mutations for more intricate operations.