Table of Contents
Laravel is a popular PHP web application framework known for its simplicity, elegance, and expressive syntax. GraphQL, on the other hand, is a modern data query and manipulation language that enables clients to retrieve only the data they need from an API.
Laravel GraphQL is a package that seamlessly integrates GraphQL into Laravel, allowing developers to build powerful and efficient APIs with ease. With Laravel GraphQL, developers can define their API schemas using the GraphQL syntax, and Laravel will automatically handle the queries, mutations, and subscriptions. CRUD with GraphQL Laravel is straightforward if you use PHP GraphQL libaries like Rebing GraphQL Laravel or Lighthouse.
We choose the Lighthouse library over Rebing GraphQL Laravel because it is beginner-friendly and does not include massive boilerplate code. Besides, it is flexible and works best with Laravel Eloquent.
One of the main advantages of using Laravel GraphQL is the reduced complexity of building APIs. It simplifies the development process by eliminating the need for developers to write boilerplate code, allowing them to focus on business logic instead. Additionally, GraphQL's ability to fetch only the required data results in faster and more efficient API responses, which can significantly improve the overall performance of web applications.
This tutorial shows you how to create, read, update, and delete fields using the Lighthouse library.
Let's get started.
CRUD with GraphQL Laravel using the Lighthouse package
CRUD (Create, Read, Update, Delete) operations are essential for any web application. In Laravel, developers can use the Lighthouse package to implement CRUD operations using GraphQL. Lighthouse is a Laravel package that simplifies the process of building a GraphQL server.
To implement CRUD operations with GraphQL in Laravel using the Lighthouse package, developers need to define their GraphQL schema, which specifies the types of data and the operations that can be performed on them. They can then define Laravel models and their corresponding GraphQL types, implement resolvers for the queries and mutations in app/GraphQL/Queries
and app/GraphQL/Mutations
, respectively.
Mutation
: Create, update, or delete data.Query
: read data.
Once the GraphQL schema is defined, developers can perform CRUD operations by sending GraphQL queries or mutations to the server. For example, to create a new user, a client can send a mutation to the server with the necessary fields for the new user. The server will create a new user in the database and return the newly created user back to the client.
Lighthouse wraps around Laravel Eloquent to simplify CRUD with graphql Laravel. Through a single file schema.graphql, you change or show data.
The schema file describes the types of data and how the client can access it. The data grouping is according to the type. The frequently used root data types are:
Set up a lab environment
Laravel
// creates a new Laravel project named "laravel_graphql"
laravel new laravel_graphql
// navigates to the new project directory
cd laravel_graphql
We create a Laravel app called laravel_graphql
and navigate to the new directory.
Lighthouse
// install the Lighthouse package via Composer, which provides GraphQL support for Laravel applications
composer require nuwave/lighthouse
// publishes the Lighthouse schema configuration file to the application's config directory
php artisan vendor:publish --tag=lighthouse-schema
// generate IDE helper files for Lighthouse, which can help with auto-completion and type-checking in IDEs like PHPStorm
php artisan lighthouse:ide-helper
// This command installs the Laravel GraphiQL package, which provides a user interface for testing GraphQL queries
composer require mll-lab/laravel-graphiql
We install the Lighthouse package as described in the installation guide. Append the "dev-master"
option if you find an error installing lighthouse.
composer require nuwave/lighthouse "dev-master"
Next, we automate the creation of the schema folder and file graphql/schema.qraphql
.
The ide-helper
improves editing experience. Lastly, we install GraphiQL, also known as the playground. GraphiQL is a browser playground for GraphQL, just like Postman for REST APIs.
Model
These commands help set up a database and generate a model and migration file for the "Post" entity in a Laravel project. The code .
command then opens the project in a code editor so that you can begin working on it.
mysql -u root -p
mysql> create database laravel_graphql;
mysql> exit;
php artisan make:model Post -m
code .
We log into MySQL database service and create a database with the name described in the project's .env
file. After that, we create a Post
model with its -m
migration.
Open the posts migration file in database/migrations
folder and add two post details: title and content.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};
With that, we are ready to migrate the changes.
php artisan migrate
Now that we have set up a lab environment, let me show you how to do CRUD with graphql Laravel step-by-step.
Create CRUD GraphQL API Schema
As explained in the first section of this tutorial, the GraphQL schema file describes data with its relations and how to access or modify it.
type Post { id: ID title: String content: String }
We create a custom data of type Post
. Each post should have three fields (id, title, and content) of ID
, String
, and String
types, respectively.
We can do CRUD with graphql Laravel on the data type, as follows.
Create
type Mutation { createPost(title: String!, content: String!): Post! @create }
The createPost
method creates a post with the supplied title and content in the Mutation
object type. The exclamation !
marks denote that the fields must be supplied when creating a post. The output is an object of the Post
object. The @create
derivative creates a new record in the database.
Read
type Query { posts: [Post] @all post(id:ID @eq): Post @find }
Using the Lighthouse's Query
object type, we describe how to retrieve all posts or one post. We will read all @all
posts as an array [Post]
of the Post
object type.
On the other hand, we will find @find
a single post in the database with its id. The @eq
derivative implies the output's data must match the specified ID. It is like a where clause which attaches the supplied id to a record in the data.
Update
type Mutation { updatePost(id:ID!, title: String, content: String): Post! @update }
The updatePost
method receives optional title or content and updates the data at the matching ID using the @update
derivative.
Delete
type Mutation { deletePost(id: ID! @eq): Post @delete }
Finally, we locate a post with its ID and delete it using the @delete
derivative.
Full Code
The Mutation type defines three mutation operations that can be performed on Post objects:
createPost
: A mutation that creates a new Post object with a requiredtitle
andcontent
field, and returns the newly created object with a@create
directive.updatePost
: A mutation that updates an existing Post object with the specified ID. Thetitle
andcontent
fields are optional, and the mutation returns the updated Post object with a@update
directive.deletePost
: A mutation that deletes an existing Post object with the specified ID. The mutation returns the deleted Post object with a@delete
directive.
The Query type defines two query operations that can be performed on Post objects:
posts
: A query that returns all Post objects with a@all
directive.post
: A query that returns a single Post object with the specified ID with an@find
directive.
These types and operations can be used to define a GraphQL schema for a Laravel application. The @create
, @update
, @delete
, @all
, and @find
directives are provided by the Lighthouse package and can be used to define the corresponding CRUD operations for the application.
type Post { id: ID title: String content: String } type Mutation { createPost(title: String!, content: String!): Post! @create updatePost(id: ID!, title: String, content: String): Post! @update deletePost(id: ID! @eq): Post @delete } type Query { posts: [Post] @all post(id:ID @eq): Post @find }
Test the CRUD Application
Start the server
php artisan serve
Launch a browser and then visit the playground: http://127.0.0.1:8000/graphiql
. Now, create the first post.
Create
Input
mutation { createPost(title: "CRUD with graphql Laravel", content: "We are creating a post now"){ id } }
Output
{ "data": { "createPost": { "id": "1" } } }
Read
Many
Input
{ posts{ id title content } }
Output
{ "data": { "posts": [ { "id": "1", "title": "CRUD with graphql Laravel", "content": "We are creating a post now" } ] } }
We could also replace the @all
with @paginate
derivative to let us control the amount of posts to view per page. Before that, let us create two more posts.
Input
{ posts(first:2, page:1){ data{ id title } } }
Output
{ "data": { "posts": { "data": [ { "id": "1", "title": "CRUD with graphql Laravel" }, { "id": "2", "title": "second post" } ] } } }
Besides the data attribute, we could inspect more information with the paginatorInfo
.
Input
{ posts(first:2, page:1){ data{ id title } paginatorInfo { count currentPage hasMorePages } } }
Output
{ "data": { "posts": { "data": [ { "id": "1", "title": "CRUD with graphql Laravel" }, { "id": "2", "title": "second post" } ], "paginatorInfo": { "count": 2, "currentPage": 1, "hasMorePages": true } } } }
One
So far, we have read many posts using the @all
and @paginate
derivates. Let's read one post with its id using the @find
derivative.
Input
{ post(id: 1){ title content } }
Output
{ "data": { "post": { "title": "CRUD with graphql Laravel", "content": "We are creating a post now" } } }
Update
Input
mutation { updatePost(id:2, title: "We are updating the second post") { id title content } }
Output
{ "data": { "updatePost": { "id": "2", "title": "We are updating the second post", "content": "Let's create the second post" } } }
Delete
Finally, let's delete the third post.
Input
mutation { deletePost(id:3){ title } }
Output
{ "data": { "deletePost": { "title": "Post 3" } } }
Then, query all posts.
Input
{ posts(first:2){ data{ id title content } paginatorInfo{ hasMorePages } } }
Output
{ "data": { "posts": { "data": [ { "id": "1", "title": "CRUD with graphql Laravel", "content": "We are creating a post now" }, { "id": "2", "title": "We are updating the second post", "content": "Let's create the second post" } ], "paginatorInfo": { "hasMorePages": false } } } }
Summary
CRUD (Create, Read, Update, and Delete) operations are an essential aspect of any web application that interacts with a database. In Laravel, CRUD operations can be implemented using GraphQL, a query language for APIs that enables clients to request the exact data they need.
Laravel provides several packages that make it easy to implement GraphQL in a Laravel application. One popular package is Lighthouse, which enables developers to define a GraphQL schema that maps to the application's database. Lighthouse also provides built-in directives that allow developers to define CRUD operations for the schema.
To implement CRUD operations with GraphQL and Lighthouse in a Laravel application, developers need to define GraphQL types for the data entities in their application, such as users, posts, and comments. They also need to define a Mutation type that defines the create, update, and delete operations for each entity, as well as a Query type that defines the read operations.
Once the schema is defined, developers can use GraphQL queries and mutations to perform CRUD operations on the data entities in their application. The Lighthouse package provides tools to generate boilerplate code for the schema and to test the queries and mutations.