GraphQL in Laravel: A Developer's Perspective

blog-banner

What is GraphQL?

GraphQL is a query language for APIs and a runtime for executing those queries with your existing data. It allows clients to request exactly what they need and nothing more.

Key Benefits: 

  • Request only the data you need
  • Nested and relational querying
  • Single endpoint for all queries

GraphQL API Routes

Route::post('/graphql', '\Nuwave\Lighthouse\Support\Http\Controllers\GraphQLController@query') 
->middleware([ 
    \Illuminate\Http\Middleware\HandleCors::class, 
]); 


 

GraphQL Schema for Blog System

Here's the GraphQL schema we used for our Laravel blog project:

scalar Upload 

type User {
	id: ID!
	name: String!
	email: String!
	posts: [Post!]! @hasMany 
} 
 
type Post {
	id: ID!
	title: String!
	description: String!
	user: User! @belongsTo
	images: [Image!]! @hasMany 
} 
 
type Image {
	id: ID!
	image: String!
	post: Post! @belongsTo 
} 
 
type Query {
	users: [User!]! @all
	posts: [Post!]! @all
	images: [Image!]! @all
	getPostById(id: ID!): Post @field(resolver: "App\\Http\\Controllers\\PostController@getPostById") 
} 

type Mutation {
	createUser(name: String!, email: String!, password: String!): User @create
	createPost(
	   title: String!,
	   description: String!,
	   user_id: ID!,
	   image: Upload!
	): Post @field(resolver: "App\\Http\\Controllers\\PostController@createPost")
	    
    updatePost(
	   id: ID!,
	   title: String,
	   description: String,
	   user_id: ID,
	   images: [Upload]
	   ): Post @field(resolver: "App\\Http\\Controllers\\PostController@updatePost")
	    
	 deletePost(id: ID!): Boolean @field(resolver: "App\\Http\\Controllers\\PostController@deletePost")
	}
 

Custom Scalar for Upload

	class Upload extends ScalarType 
	{ 
	    public function __construct() {
	        parent::__construct([
	            'name' => 'Upload',
	            'description' => 'The `Upload` scalar type represents a file upload.'
	         ]);
	   }
	   
	   public function serialize($value) {
	        return $value;
	   }
	   
	   public function parseValue($value) {
	        return (new LighthouseUpload())->parseValue($value);
	   }
	   
	   public function parseLiteral($valueNode, array $variables = null)
	   {
	        throw new \Exception('Upload cannot be passed as a literal.');
	   }
	} 
		


 

GraphQL Controller Methods

Create Post

    public function createPost($root, array $args)
    {
        $post = Post::create([
            'title' => $args['title'],
            'description' => $args['description'],
            'user_id' => $args['user_id']
        ]); 
	
    	if ($args['image']) {
    	    $imagePath = $args['image']->store('post_images', 'public');
    	        Image::create([
    	            'image' => $imagePath,
    	            'post_id' => $post->id
    	       ]);
    	 }
	 
	    return $post->load('images');
    }

Update Post

    public function updatePost($root, array $args)
    {
        $post = Post::findOrFail($args['id']);
        $post->update([
            'title' => $args['title'],
            'description' => $args['description'],
            'user_id' => $args['user_id']
        ]);
        
        if (isset($args['images']) && is_array($args['images'])) {
            foreach ($args['images'] as $imageFile) {
                $path = $imageFile->store('post_images', 'public');
                        Image::create([
                            'image' => $path,
                            'post_id' => $post->id
                        ]);
            }
         }
         
         return $post->load('images');
    }
    

Delete Post

    public function deletePost($root, array $args)
    {
        $post = Post::findOrFail($args['id']);
        foreach ($post->images as $image) {
            Storage::disk('public')->delete($image->image);
            $image->delete();
        }
        return $post->delete();
    }
    

Get Post by ID

    public function getPostById($root, array $args)
    {
        return Post::with(['images', 'user'])->findOrFail($args['id']);
    }
    

Why use $root and $args?

  • $args contains the actual input values sent by the client.
  • $root is useful when resolving nested fields but is usually null at the top level.

Success Story of Laravel Migration

In one of our recent projects, we successfully migrated a client’s legacy Core PHP application to Laravel, delivering significant improvements in performance, scalability, and security. Our team revamped the application architecture, optimized database operations, and elevated the overall user experience—ensuring business continuity with zero downtime.

PHP system
  • Challenge: An outdated Core PHP system with limited scalability and growing maintenance overhead.
  • Our Solution: A comprehensive Laravel migration to modernize the tech stack, boost performance, and future-proof the application.
  • Result: Improved security, faster application speed, and enhanced code maintainability.

Read More: Migration from Core PHP to Laravel.

Conclusion

GraphQL offers a powerful and flexible way to interact with APIs, especially when dealing with complex, relational data structures like users, posts, and images. As part of our Laravel Web Development Services, integrating GraphQL into Laravel projects using Lighthouse can significantly simplify data fetching while enhancing performance by reducing over-fetching and under-fetching.

Whether you're building a simple blog or a large-scale enterprise application, our Laravel Development Services ensure a seamless GraphQL integration that makes your backend more efficient and your frontend more responsive. With a single endpoint and a strongly typed schema, GraphQL empowers developers to build scalable, maintainable applications with confidence and ease.

Contact us

For Your Business Requirements

Text to Identify Refresh CAPTCHA
Background Image Close Button

2 - 4 October 2024

Hall: 10, Booth: #B8 Brussels, Belgium