Defining Your First Schema, Queries, and Mutations with Laravel and GraphQL

 



GraphQL has quickly become a popular choice for building APIs due to its flexibility and efficiency. Unlike REST, GraphQL allows clients to specify exactly what data they need, making it easier to avoid over-fetching or under-fetching information. In this article, we'll cover how to define your first GraphQL schema, queries, and mutations in a Laravel application using the Rebing GraphQL package.


Prerequisites


Before getting started, make sure you have the following:

  • A Laravel application set up.
  • Familiarity with GraphQL concepts (types, queries, mutations).
  • Composer installed.


Step 1: Installing Rebing GraphQL in Laravel


First, we need to install the Rebing GraphQL package. Run the following command:


composer require rebing/graphql-laravel


After the installation is complete, publish the configuration file:


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


This will create the configuration file at `config/graphql.php`.


Step 2: Defining the GraphQL Schema


The GraphQL schema is the foundation of your API. It defines the data structure and available operations. In Laravel, you define your schema within the `graphql.php` configuration file.


Here’s an example schema structure:


'schemas' => [

    'default' => [

        'query' => [

            'exampleQuery' => App\GraphQL\Queries\ExampleQuery::class,

        ],

        'mutation' => [

            'createItem' => App\GraphQL\Mutations\CreateItemMutation::class,

        ],

        'types' => [

            'ItemType' => App\GraphQL\Types\ItemType::class,

        ],

    ],

],


This configuration registers queries, mutations, and types for your GraphQL API.


Step 3: Creating Your First Type


In GraphQL, types represent the structure of your data. Let’s create a simple `ItemType` that defines the fields for an item.


Run the following command to generate a type:


php artisan make:graphql:type ItemType


In the generated `ItemType` class, define the fields that your type should expose:


namespace App\GraphQL\Types;


use Rebing\GraphQL\Support\Type as GraphQLType;

use GraphQL\Type\Definition\Type;


class ItemType extends GraphQLType

{

    protected $attributes = [

        'name' => 'Item',

        'description' => 'A type representing an item',

    ];


    public function fields(): array

    {

        return [

            'id' => [

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

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

            ],

            'name' => [

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

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

            ],

            'description' => [

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

                'description' => 'A description of the item',

            ],

        ];

    }

}


This type defines three fields: `id`, `name`, and `description`.


Step 4: Creating Your First Query


Queries are used to retrieve data. Let’s create a simple query to fetch all items.


Run the following command to generate a query:


php artisan make:graphql:query ItemQuery


In the `ItemQuery` class, define how to fetch the data:


namespace App\GraphQL\Queries;


use Rebing\GraphQL\Support\Query;

use GraphQL\Type\Definition\Type;

use App\Models\Item;

use GraphQL;


class ItemQuery extends Query

{

    protected $attributes = [

        'name' => 'items',

    ];


    public function type(): Type

    {

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

    }


    public function resolve($root, $args)

    {

        return Item::all();

    }

}


This query returns a list of items from the database.


Step 5: Creating Your First Mutation


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


Run the following command to generate a mutation:


php artisan make:graphql:mutation CreateItemMutation


In the `CreateItemMutation` class, define how to handle the mutation:


namespace App\GraphQL\Mutations;


use Rebing\GraphQL\Support\Mutation;

use GraphQL\Type\Definition\Type;

use App\Models\Item;

use GraphQL;


class CreateItemMutation extends Mutation

{

    protected $attributes = [

        'name' => 'createItem',

    ];


    public function type(): Type

    {

        return GraphQL::type('Item');

    }


    public function args(): array

    {

        return [

            'name' => [

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

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

            ],

            'description' => [

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

                'description' => 'The description of the item',

            ],

        ];

    }


    public function resolve($root, $args)

    {

        return Item::create([

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

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

        ]);

    }

}


This mutation takes `name` and `description` as input arguments and creates a new item in the database.


Step 6: Registering Queries and Mutations


To make the query and mutation available in your GraphQL API, register them in the `config/graphql.php` file:


'schemas' => [

    'default' => [

        'query' => [

            'items' => App\GraphQL\Queries\ItemQuery::class,

        ],

        'mutation' => [

            'createItem' => App\GraphQL\Mutations\CreateItemMutation::class,

        ],

    ],

],


Step 7: Testing Your GraphQL API


Start your Laravel development server:


php artisan serve


You can access the GraphQL endpoint at `http://localhost:8000/graphql`. Use a tool like GraphiQL or Postman to test the API.


For example, to fetch all items:


{

  items {

    id

    name

    description

  }

}


To create a new item:


mutation {

  createItem(name: "New Item", description: "This is a new item") {

    id

    name

    description

  }

}


Setting up your first GraphQL schema, queries, and mutations in Laravel using the Rebing GraphQL package is straightforward. By defining types, queries, and mutations, you can build flexible and efficient APIs that give clients control over the data they fetch. As you expand your application, you can continue to enhance your schema to support more complex operations and data structures.