Using Laravel Eloquent Models with GraphQL Queries and Mutations


Integrating Laravel Eloquent models with GraphQL queries and mutations allows you to create a seamless and efficient way to interact with your database using the flexibility of GraphQL. By leveraging Laravel's powerful Eloquent ORM and the structured querying capabilities of GraphQL, you can provide a modern API experience with efficient data retrieval and manipulation.


This article will guide you through setting up Laravel Eloquent models with GraphQL for handling queries and mutations. We’ll cover how to create a basic GraphQL schema, define queries and mutations, and link them to Eloquent models to manage data.


Prerequisites


Before we start, ensure that you have the following:

  • A Laravel project set up.
  • A GraphQL package installed, such as Rebing GraphQL.


To install the Rebing GraphQL package, you can run:


composer require rebing/graphql-laravel


Next, publish the configuration:


php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"


Setting Up Your First Eloquent Model


For this example, let's assume we have a simple `Post` model with the following properties:

  • `id`: integer
  •  `title`: string
  •  `content`: text
  • `user_id`: integer (foreign key to a `User` model)


Create the `Post` model and migration:


php artisan make:model Post -m


In the migration file, define the table structure:


Schema::create('posts', function (Blueprint $table) {

    $table->id();

    $table->string('title');

    $table->text('content');

    $table->foreignId('user_id')->constrained('users');

    $table->timestamps();

});


Run the migration:


php artisan migrate


Defining GraphQL Types for Eloquent Models


To use the `Post` model in GraphQL, we need to define a GraphQL type that maps to the `Post` model's properties.


Create a `PostType`:


php artisan make:graphql:type PostType


In the generated `PostType`, define the fields:


namespace App\GraphQL\Types;


use App\Models\Post;

use GraphQL\Type\Definition\Type;

use Rebing\GraphQL\Support\Type as GraphQLType;


class PostType extends GraphQLType

{

    protected $attributes = [

        'name' => 'Post',

        'description' => 'A type representing a blog post',

        'model' => Post::class,

    ];


    public function fields(): array

    {

        return [

            'id' => [

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

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

            ],

            'title' => [

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

                'description' => 'The title of the post',

            ],

            'content' => [

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

                'description' => 'The content of the post',

            ],

            'user_id' => [

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

                'description' => 'The ID of the user who created the post',

            ],

        ];

    }

}


This type maps the Eloquent model properties to GraphQL fields, allowing GraphQL to understand what data to expect and how to resolve it.


Creating GraphQL Queries with Eloquent Models


Next, we will define a GraphQL query that retrieves a list of posts from the database using Eloquent.


Create a `PostQuery`:


php artisan make:graphql:query PostQuery


In the `PostQuery` class, implement the query logic:


namespace App\GraphQL\Queries;


use App\Models\Post;

use GraphQL\Type\Definition\Type;

use Rebing\GraphQL\Support\Facades\GraphQL;

use Rebing\GraphQL\Support\Query;


class PostQuery extends Query

{

    protected $attributes = [

        'name' => 'posts',

    ];


    public function type(): Type

    {

        return Type::listOf(GraphQL::type('Post'));

    }


    public function resolve($root, $args)

    {

        return Post::all();

    }

}


This query retrieves all posts using Eloquent's `all()` method and returns them as a list of `PostType`.


To register this query, add it to the `config/graphql.php` file:


'queries' => [

    'posts' => \App\GraphQL\Queries\PostQuery::class,

],


Defining Mutations with Eloquent Models


Mutations allow you to create, update, or delete data through GraphQL. Let’s create a mutation for adding a new post.


Create a `CreatePostMutation`:


php artisan make:graphql:mutation CreatePostMutation


In the `CreatePostMutation`, define the fields and logic for creating a post:


namespace App\GraphQL\Mutations;


use App\Models\Post;

use GraphQL\Type\Definition\Type;

use Rebing\GraphQL\Support\Facades\GraphQL;

use Rebing\GraphQL\Support\Mutation;


class CreatePostMutation extends Mutation

{

    protected $attributes = [

        'name' => 'createPost',

    ];


    public function type(): Type

    {

        return GraphQL::type('Post');

    }


    public function args(): array

    {

        return [

            'title' => [

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

                'description' => 'The title of the post',

            ],

            'content' => [

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

                'description' => 'The content of the post',

            ],

            'user_id' => [

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

                'description' => 'The ID of the user who is creating the post',

            ],

        ];

    }


    public function resolve($root, $args)

    {

        return Post::create([

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

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

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

        ]);

    }

}


This mutation accepts `title`, `content`, and `user_id` as arguments, and uses Eloquent’s `create()` method to store the data.


Register the mutation in `config/graphql.php`:


'mutations' => [

    'createPost' => \App\GraphQL\Mutations\CreatePostMutation::class,

],


Querying and Mutating Data with Eloquent Models


Now that we have set up a query and a mutation, let's test them.


Testing the Query


To fetch all posts, you can send the following GraphQL query:


{

  posts {

    id

    title

    content

    user_id

  }

}


This will return a list of all posts from the database.


Testing the Mutation


To create a new post, use the following mutation:


mutation {

  createPost(title: "New GraphQL Post", content: "This is a post created via GraphQL.", user_id: 1) {

    id

    title

    content

    user_id

  }

}


This mutation will create a new post in the database and return the created post’s details.


Best Practices for Using Eloquent with GraphQL


1. Use Eloquent Scopes: To simplify complex queries, use Eloquent scopes for reusable query logic, and call them within your GraphQL query resolvers.

2. Eager Load Relationships: Use Eloquent's `with()` method to load relationships when needed to avoid the N+1 query problem.

3. Validation: Use Laravel’s validation to ensure that input data is correct before processing it in mutations.

4. Error Handling: Handle errors gracefully in mutations to provide better feedback to API consumers.

5. Pagination: Implement pagination for queries that return large datasets using Laravel’s built-in pagination tools.


Integrating Laravel Eloquent models with GraphQL queries and mutations allows you to create flexible and efficient APIs that can query and manipulate data seamlessly. By using Eloquent with GraphQL, you can leverage Laravel’s database capabilities and GraphQL’s structured data querying, making it easy to build powerful APIs. Whether you’re creating a simple CRUD application or a more complex system, understanding how to tie Eloquent models into your GraphQL setup is an essential skill for modern API development.


By following the examples in this article, you should be well on your way to building and extending a GraphQL API using Laravel’s Eloquent models.