GraphQL provides a flexible and efficient way to interact with APIs, allowing clients to request the data they need. In Laravel, the Lighthouse package makes it easy to implement GraphQL. This article will guide you through writing complex GraphQL queries and mutations in a Laravel application.
Understanding GraphQL
GraphQL, developed by Facebook, is a query language for APIs that enables clients to request specific data structures. It consists of three main components:
1. Queries: For fetching data.
2. Mutations: For modifying data.
3. Subscriptions: For real-time data updates.
Setting Up GraphQL with Laravel
Before diving into complex queries and mutations, ensure you have GraphQL set up in your Laravel application using the Lighthouse package.
1. Install Lighthouse:
composer require nuwave/lighthouse
2. Publish Configuration:
php artisan vendor:publish --provider="Nuwave\Lighthouse\LighthouseServiceProvider"
3. Define Schema:
Create and define your GraphQL schema in the `graphql/schema.graphql` file.
Writing Complex GraphQL Queries
Complex queries often involve fetching nested and related data, filtering, sorting, and pagination. Let's explore these aspects with examples.
Example Schema:
type Query {
users(filter: UserFilter, sort: UserSort, paginate: PaginateInput): UserConnection
user(id: ID!): User
}
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
body: String!
comments: [Comment!]!
}
type Comment {
id: ID!
content: String!
}
input UserFilter {
name: String
email: String
}
input UserSort {
field: String
order: String
}
input PaginateInput {
page: Int
limit: Int
}
type UserConnection {
data: [User!]!
paginatorInfo: PaginatorInfo!
}
type PaginatorInfo {
count: Int!
currentPage: Int!
lastPage: Int!
perPage: Int!
total: Int!
}
Complex Query Example:
query {
users(filter: { name: "John" }, sort: { field: "email", order: "ASC" }, paginate: { page: 1, limit: 10 }) {
data {
id
name
email
posts {
id
title
comments {
id
content
}
}
}
paginatorInfo {
count
currentPage
lastPage
perPage
total
}
}
}
Resolvers:
namespace App\GraphQL\Resolvers;
use App\Models\User;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
class UserResolver
{
public function users($root, array $args, GraphQLContext $context)
{
$query = User::query();
// Apply filtering
if (isset($args['filter'])) {
if (isset($args['filter']['name'])) {
$query->where('name', 'like', '%' . $args['filter']['name'] . '%');
}
if (isset($args['filter']['email'])) {
$query->where('email', 'like', '%' . $args['filter']['email'] . '%');
}
}
// Apply sorting
if (isset($args['sort'])) {
$query->orderBy($args['sort']['field'], $args['sort']['order']);
}
// Apply pagination
$pagination = $query->paginate($args['paginate']['limit'] ?? 15, ['*'], 'page', $args['paginate']['page'] ?? 1);
return [
'data' => $pagination->items(),
'paginatorInfo' => [
'count' => $pagination->count(),
'currentPage' => $pagination->currentPage(),
'lastPage' => $pagination->lastPage(),
'perPage' => $pagination->perPage(),
'total' => $pagination->total(),
],
];
}
public function user($root, array $args, GraphQLContext $context)
{
return User::findOrFail($args['id']);
}
}
Writing Complex GraphQL Mutations
Mutations in GraphQL allow you to create, update, or delete data. Complex mutations may involve nested inputs, validations, and transactions.
Example Schema:
type Mutation {
createUser(input: CreateUserInput!): User
updateUser(id: ID!, input: UpdateUserInput!): User
}
input CreateUserInput {
name: String!
email: String!
posts: [CreatePostInput!]!
}
input CreatePostInput {
title: String!
body: String!
comments: [CreateCommentInput!]!
}
input CreateCommentInput {
content: String!
}
input UpdateUserInput {
name: String
email: String
}
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
Complex Mutation Example:
mutation {
createUser(input: {
name: "John Doe",
email: "john@example.com",
posts: [{
title: "My First Post",
body: "This is the body of my first post",
comments: [{
content: "Great post!"
}]
}]
}) {
id
name
email
posts {
id
title
comments {
id
content
}
}
}
}
Resolvers:
namespace App\GraphQL\Resolvers;
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
use Illuminate\Support\Facades\DB;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
class UserResolver
{
public function createUser($root, array $args, GraphQLContext $context)
{
return DB::transaction(function () use ($args) {
$user = User::create($args['input']);
if (isset($args['input']['posts'])) {
foreach ($args['input']['posts'] as $postInput) {
$post = new Post($postInput);
$user->posts()->save($post);
if (isset($postInput['comments'])) {
foreach ($postInput['comments'] as $commentInput) {
$comment = new Comment($commentInput);
$post->comments()->save($comment);
}
}
}
}
return $user;
});
}
public function updateUser($root, array $args, GraphQLContext $context)
{
$user = User::findOrFail($args['id']);
$user->update($args['input']);
return $user;
}
}
Writing complex GraphQL queries and mutations in Laravel using the Lighthouse package provides a powerful way to interact with your application's data. You can efficiently manage and query your data by defining a detailed schema, creating resolvers, and leveraging GraphQL's flexibility. This approach improves performance and enhances the developer and user experience by providing precise and efficient data fetching and manipulation capabilities. Embrace GraphQL to take your Laravel application to the next level.
0 Comments