FOR DEVELOPERS

Setting up a GraphQL Server Using Laravel

Setting A GraphQL Server Using Laravel

GraphQL is the language of APIs and can be used to fetch data from a server. This language also allows the clients to specify the exact data that is needed. It is a powerful query language used to interact with your API. As compared to the alternative architectures, such as the REST, GraphQL provides additional benefits.

Apart from the benefits, it also serves as an endpoint for mobile and single-page websites and applications. This language enables you to query the related and nested data and streamline the single round trip to the server.

Although the GraphQL community has grown immensely, the availability of documentation on how to use this technology is very little. In this article, we will learn how to create a GraphQL server using the Laravel framework along with some examples, mutations, query relationships, and authentications.

Getting started with GraphQL

It is quite easy to start with GraphQL. You need to put a Laravel0 environment in the terminal and run this command.

composer create-project laravel/laravel graphql-laravel

Next, you need to install the GraphQL Llaravel package by running the configuration below:

composer require rebing/graphql-laravel

Once you are done with the installation, you need to update the following code:

config/graphql.php

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

How to setup GraphQL server using Laravel.webp

Creating migration, resources & controllers

You need to build and explain the models where you will demarcate the relationship between the entities. You will also define the new database schemas and create new migrations.

Update the following configuration:

php artisan make:model Post -mcr

To do so, you need to create a ‘hasMany’ relationship between the posts and the users.

public function user()
{
	return $this->belongsTo(User::class);
}

Code source

Creating a new migration

Laravel offers a useful default migration. You simply need to add a new migration for new posts by running the following command:

php artisan make:migration create_post_table

Running the above code creates a new migration in the ‘database/migrations’. Next you need to define the schema in the migration file:

Schema::create('posts', function (Blueprint $table) {
            $table->id();
             $table->integer('user_id')->unsigned();
            $table->string('title');
            $table->text('comment');
            $table->timestamps();
        });

Next, you have to revise the existing ‘.env’ file to define your database. The code below will help you establish a new connection.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=graphql-laravel
DB_USERNAME=root
DB_PASSWORD=

Now you need to migrate the command to create new Users and Post tables.

php artisan migrate

Creating a new post

Run the following code to build a new post:

php artisan make:factory PostFactory

After creating a new file within the ‘database>factories’ directory, you need to define the column names and other elements you want to have within the definition. Here is the code to do the same:

use Illuminate\Support\Str;

public function definition() { return [ 'user_id' => rand(1,5), 'title' => $this->faker->name(), 'comment' => $this->faker->realText(180) ]; }

Creating a new database seeder

You can create a new execution instance for both the Posts and User factories within the seeder class.

The code given below creates 7 posts and 7 users with their corresponding IDs:

public function run()
    {
        \App\Models\User::factory(7)->create();
    \App\Models\Post::factory(7)->create();
}

After running the above code, you need to artisan seeder command:

php artisan db:seed

Creating a new user query

Here is the code to create a new user query:

<?php

namespace App\GraphQL\Type;

use App\Models\User; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Type as GraphQLType;

class UserType extends GraphQLType { protected $attributes = [ 'name' => 'User', 'description' => 'A user', 'model' => User::class, ];

public function fields(): array
{
    return [
        &#39;id&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::int()),
            &#39;description&#39; =&gt; &#39;The id of the user&#39;,
        ],
        &#39;name&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
            &#39;description&#39; =&gt; &#39;The name of user&#39;,
        ],
        &#39;email&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
            &#39;description&#39; =&gt; &#39;The email of user&#39;
        ],
    ];
}

}

In the above code fragment, you need to have the namespace to the specific User model. You also need to have a protected $attributes array that will describe the particular User model. Apart from that, you also need to have a public field function that returns the $attributes array. You have to define the schema that includes the columns within this public field function.

Adding a type to the configuration

Use the code fragment given below to add a new UserType to the configuration you created previously:

'types' => [
        App\GraphQL\Type\UserType::class
    ],

Defining a new user query

After adding a type to the configuration, you need to define a query that returns a list. On top of that, you also need to specify all the arguments you want to include within the method.

Here is the code to define a new user query:

<?php

namespace App\GraphQL\Type;

use GraphQL; use App\Models\User; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Type as GraphQLType;

class UserType extends GraphQLType { protected $attributes = [ 'name' => 'User', 'description' => 'A user', 'model' => User::class, ];

public function type(): Type
{
    return Type::nonNull(Type::listOf(Type::nonNull(GraphQL::type(&#39;User&#39;))));
}

public function args(): array
{
    return [
        &#39;id&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::int()),
            &#39;description&#39; =&gt; &#39;The id of the user&#39;,
        ],
        &#39;name&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
            &#39;description&#39; =&gt; &#39;The name of user&#39;,
        ],
        &#39;email&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
            &#39;description&#39; =&gt; &#39;The email of user&#39;,
        ]
    ];
}

public function resolve($root, $args)
{        
    if (isset($args[&#39;id&#39;])) {
        return User::whereId($args[&#39;id&#39;])-&gt;get();
    }
    
    if (isset($args[&#39;name&#39;])) {
        return User::whereName($args[&#39;name&#39;])-&gt;get();
    }

    if (isset($args[&#39;email&#39;])) {
        return User::whereEmail($args[&#39;email&#39;])-&gt;get();
    }

    return User::all();
}

}

In the code fragment above, we have used the required namespace with ‘ App\Models\User’. We have also defined the attributes and extended the GraphQLType.

The method we have used here fetches the data from the database. If there are any arguments then the ‘if’ block gets executed.

Adding a query to the configuration

Moving ahead, you need to add the given query to the following configuration file:

app > config > graphql.php

'schemas' => [ 'default' => [ 'query' => [ App\GraphQL\Query\UsersQuery::class, ], 'mutation' => [ // ExampleMutation::class, ], 'types' => [ // ExampleType::class, ], 'middleware' => [], 'method' => ['get', 'post'], ], ],

How to fetch all users using a query

Below is the code to fetch all the users using a query:

query {
    users {
        id, name , email
    }
}

Creating a post-relationship with the user

To create a Post Relationship with the user, you need to define a PostType. The approach is very similar to that of UserType. To do so, you need to navigate to:
app > Type > PostType.php file and add the following:

<?php

namespace App\GraphQL\Type;

use GraphQL; 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 post', 'model' => Post::class, ];

public function args(): array
{
    return [
        &#39;id&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::int()),
            &#39;description&#39; =&gt; &#39;The id of the post&#39;,
        ],
        &#39;title&#39; =&gt; [
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
            &#39;description&#39; =&gt; &#39;The title of post&#39;,
        ],
    ];
}

}

The above code helps you extend the Query to the PostQuery class and protects the $attributes array. Apart from that you also have a field’s function that returns the array with the basic attributes including the comment, ID, and title.

Furthermore, you also have a type within the ‘args’ function that displays various types of data along with a description.

Creating a PostsQuery

To create a PostsQuery, all you need to do is to add the following code to ‘app > GraphQL > Query > PostsQuery.php’:

<?php 

namespace App\GraphQL\Query;

use Closure; use App\Models\Post; use Rebing\GraphQL\Support\Facades\GraphQL; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; use Rebing\GraphQL\Support\Query;

class PostsQuery extends Query { protected $attributes = [ 'name' => 'posts', ];

public function type(): Type
{
    return Type::nonNull(Type::listOf(Type::nonNull(GraphQL::type(&#39;Post&#39;))));
}

public function args(): array
{
    return [
        &#39;id&#39; =&gt; [
            &#39;name&#39; =&gt; &#39;id&#39;, 
            &#39;type&#39; =&gt; Type::int(),
        ],
        &#39;title&#39; =&gt; [
            &#39;name&#39; =&gt; &#39;title&#39;, 
            &#39;type&#39; =&gt; Type::string(),
        ]
    ];
}

public function resolve($root, $args)
{        
    if (isset($args[&#39;id&#39;])) {
        return Post::whereId($args[&#39;id&#39;])-&gt;get();
    }
    
    if (isset($args[&#39;title&#39;])) {
        return Post::whereTitle($args[&#39;title&#39;])-&gt;get();
    }

    return Post::all();
}

}

If there are any arguments, then the ‘if’ block gets executed. This helps you filter every field based on the user requests.

Creating a mutation

This is the final phase of setting up a GraphQL server. In this step, you will see how to set a new mutation. This new mutation will help us with the operations that involve modifying the server state.

To create a new mutation folder within ‘app > Mutation > CreateUserMutation.php’, add the following code to the ‘CreateUserMutation.php’ file.

<?php

namespace App\GraphQL\Mutation;

use Closure; use App\Models\User; use GraphQL; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\ResolveInfo; use Rebing\GraphQL\Support\Mutation;

class CreateUserMutation extends Mutation { protected $attributes = [ 'name' => 'users' ];

public function type(): Type
{
    return Type::nonNull(GraphQL::type(&#39;User&#39;));
}

public function args(): array
{
    return [
        &#39;name&#39; =&gt; [&#39;
            name&#39; =&gt; &#39;name&#39;, 
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
        ],
        &#39;email&#39; =&gt; [&#39;
            name&#39; =&gt; &#39;email&#39;, 
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
        ],
        &#39;password&#39; =&gt; [
            &#39;name&#39; =&gt; &#39;password&#39;, 
            &#39;type&#39; =&gt; Type::nonNull(Type::string()),
        ]
    ];
}

public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
    return User::firstOrCreate(
        [   &#39;email&#39; =&gt; $args[&#39;email&#39;]],
        [   &#39;name&#39; =&gt; $args[&#39;name&#39;],
            &#39;password&#39; =&gt; bcrypt($args[&#39;password&#39;])
        ]);
}

}

The resolve method helps the application users to sign up and create their own records. This approach accepts Argos as a parameter and uses the ‘firstOrCreate’ methodology to ensure that all users have a unique identifier.

We have made use of multiple built-in schemas, and created mutations, middleware, and custom queries. With Lighthouse, you can create your own customized schemas but we have limited our work to build the GraphQL server. The next time you want to set up an API for a single-page application, you can consider GraphQL to deal with your data query.

Author

  • Setting up a GraphQL Server Using Laravel

    Jay Galiyal

    Jay is a seasoned writer with 7+ years of experience in content marketing. Long-form content, copywriting, and UX writing are his strengths. He also enjoys singing, cooking, and composing poetry.

Frequently Asked Questions

Yes. Laravel allows the developers to set up a GraphQL server and also offers complete flexibility to customize the same to address the different project requirements.

Yes. The graphql-php is a feature using which you can implement GraphQL in PHP. This graphql-php feature converts the GraphQL query to a PHP array. This is done with the help of the resolve function in every field.

Setting up and implementing a GraphQl server is pretty straightforward. Follow these steps:

  1. Firstly, you need to select a framework like Laravel to implement your GraphQL server.
  2. After that, you need to define a schema that will allow your framework to route the incoming requests and queries.
  3. You should create multiple Resolver functions that tell the framework what to return and what type of queries to handle.
  4. Have an endpoint.
  5. Finally, you need to define a client-side query that retrieves the required data.

GraphQL server is a powerful server-side implementation that exposes your data as the GraphQL API that helps your client apps to send requests for the data. These client applications can be mobile applications, single-page websites, or anything.

YES & NO as that depends on the requirement. GraphQL is a query language with runtime for addressing the queries with the existing data. GraphQL offers a complete description of the data in the API. Apart from that, it also enables your clients to have what they need and offers you powerful developer tools.

If you are working on the client-side then you do not need any server.

View more FAQs
Press

Press

What’s up with Turing? Get the latest news about us here.
Blog

Blog

Know more about remote work. Checkout our blog here.
Contact

Contact

Have any questions? We’d love to hear from you.

Hire remote developers

Tell us the skills you need and we'll find the best developer for you in days, not weeks.