Maybe one day you will have a task to integrate Laravel and GraphQL into one app. Or to create GraphQL API by using only Laravel. In this short article, I’m going to show you how you can do this by using one composer package — and how you will build all schemas, types, and other features of the GraphQL inside your Laravel app.
Let’s begin! 🔥
In the first step, let’s create a new project:
$ composer create-project laravel/laravel laravel-graphql
Go to the folder of this project and install the next composer package:
$ composer require rebing/graphql-laravel
Now publish a GraphQL provider:
$ php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"
And the last step in the configuration of the database connection:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_graphql
DB_USERNAME=root
DB_PASSWORD=
Let’s create a new model named Post:
$ php artisan make:model Post -m
And now we need to open the migration file of this model:
<?php
// 2022_09_27_201311_create_posts_table.php
// ...
public function up()
{
Schema::create('posts', function(Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->string('author');
$table->timestamps();
});
}
// ...
Now we need to launch migrate command:
$ php artisan migrate
It’s time to create a new GraphQL type, so here is the PostType file:
// app/GraphQL/Types/PostType.php
namespace App\GraphQL\Types;
use App\Models\Post;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;
class PostType extends GraphQLType
{
protected $attributes = [
'name' => 'Post',
'description' => 'Collection of posts',
'model' => Post::class
];
public function fields(): array
{
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => 'ID of post'
],
'title' => [
'type' => Type::nonNull(Type::string()),
'description' => 'Title of the post'
],
'description' => [
'type' => Type::nonNull(Type::string()),
'description' => 'Description of the post'
],
'author' => [
'type' => Type::nonNull(Type::string()),
'description' => 'Author of the post'
]
];
}
}
Great, it’s time to create a new query to get all posts from the database. To do that, create a new file named PostQuery.php in the app/GraphQL/Queries folder and write the following code:
<?php
// app/GraphQL/Queries/PostQuery.php
namespace App\GraphQL\Queries;
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 PostQuery extends Query
{
protected $attributes = [
'name' => 'posts'
];
// We will need to create a type() function to define
// object type of the query
public function type(): Type
{
return Type::nonNull(Type::listOf(Type::nonNull(GraphQL::type('Post'))));
}
// And now it's time to create resolve function
public function resolve($root, array $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
return Post::all();
}
}
Amazing 💥 Before we gonna include this object type and query in the GraphQL settings of the app — let’s create a new seeder for the posts.
Let’s type the next command in the terminal:
$ php artisan make:seeder PostSeeder
And now let’s also generate a factory for the posts:
$ php artisan make:factory PostFactory
Now open this factory and write the following code:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
*/
class PostFactory extends Factory
{
/**
* Define the model's default state
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'title' => fake()->text(30),
'description' => fake()->text(50),
'author' => fake()->name()
];
}
}
The next step is to write the following code in the Post seeder:
<?php
namespace Database\Seeders;
use App\Models\Post;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Post::factory(20)->create();
}
}
Before we gonna seeder of the posts, don’t forget to configure the “.env” file:
$ php artisan db:seed --class=PostSeeder
Super, now open config/graphql.php, and let’s include this object type and query in the configuration:
<?php
use App\GraphQL\Types\PostType;
use App\GraphQL\Queries\PostQuery;
return [
// ...
'schemas' => [
'default' => [
'query' => [
PostQuery::class
],
'mutation' => [],
'types' => [
PostType::class
],
'middleware' => null,
'method' => ['GET', 'POST'],
'execution_middleware' => null
],
]
// ...
];
Now it’s time to start the local server of the app:
$ php artisan serve
And now open http://localhost:8000/graphqil:
If you open the main query — you will that now we have a query to get all posts:
Okay, now let’s try to make a request to get all posts from the database:
Click on the play button and you will see all posts from the database:
Perfect 🔥 We just created the first query for GraphQL API to get all posts from the database.
First of all, let’s open Post model file:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'description', 'author'];
}
And now we need to create a new mutation for the post creation, so create a new file app/GraphQL/Mutations/PostMutation.php:
<?php
namespace App\GraphQL\Mutations;
use Closure;
use App\Models\Post;
use GraphQL;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Mutation;
class PostMutation extends Mutation {
protected $attributes = [
'name' => 'createPost'
];
public function type(): Type
{
return Type::nonNull(GraphQL::type('Post'));
}
public function args(): array
{
return [
'title' => [
'name' => 'title',
'type' => Type::string(),
'rules' => ['required']
],
'description' => [
'name' => 'description',
'type' => Type::string(),
'rules' => ['required']
],
'author' => [
'name' => 'author',
'type' => Type::string(),
'rules' => ['required']
]
];
}
public function resolve($root, array $args, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
$Post = Post::create([
'title' => $args['title'],
'description' => $args['description'],
'author' => $args['author']
]);
return $Post;
}
}
Super, now let’s open the configuration of the GraphQL in the app:
<?php
use App\GraphQL\Types\PostType;
use App\GraphQL\Queries\PostQuery;
use App\GraphQL\Mutations\PostMutation;
return [
// ...
'schemas' => [
'default' => [
'query' => [
PostQuery::class
],
'mutation' => [
PostMutation::class
],
'types' => [
PostType::class
],
'middleware' => null,
'method' => ['GET', 'POST'],
'execution_middleware' => null
],
]
// ...
];
Open now again GraphiQL and try to create a new post:
And now let’s make a request to get all posts:
As you can see all works perfectly and the post that we just created is now in the posts list.
Yeah, that was a really simple example of how you can build GraphQL API with Laravel. We talked shortly about queries and mutations, and I showed you how to configure all this stuff and how this works ✌️😎