Introduction to GraphQL with PHP: Why You Should Try It
\n\nGraphQL is a modern query language for APIs, developed by Facebook. Unlike REST, where each endpoint returns a fixed data structure, GraphQL allows the client to request only the fields it needs. This reduces the amount of data transferred and simplifies the development of complex applications.
\n\nIn this tutorial, we will create a full-fledged GraphQL API in PHP using the webonyx/graphql-php library. You will learn how to define a schema, write resolvers, handle queries and mutations, and test the API via GraphiQL.
\n\nIt is assumed that you have PHP 8.0+ and Composer installed. If not, start by installing them.
\n\nProject Installation and Setup
\n\nStep 1: Creating the Project and Installing Dependencies
\n\nCreate a new directory for the project and initialize Composer:
\n\nmkdir graphql-php-tutorial\ncd graphql-php-tutorial\ncomposer init\n\nInstall the webonyx/graphql-php library:
composer require webonyx/graphql-php\n\nAlso install nikic/fast-route for simple routing (optional but convenient):
composer require nikic/fast-route\n\nStep 2: Project Structure
\n\nCreate the following folder structure:
\n\ngraphql-php-tutorial/\n├── src/\n│ ├── Schema/\n│ │ └── schema.php\n│ ├── Resolvers/\n│ │ ├── QueryResolver.php\n│ │ └── MutationResolver.php\n│ └── Data/\n│ └── Database.php\n├── public/\n│ └── index.php\n├── vendor/\n└── composer.json\n\nCreating the GraphQL Schema
\n\nStep 3: Defining Types and Schema
\n\nLet's create a simple data model: User and Post. Open src/Schema/schema.php and add the following code:
<?php\n\nnamespace App\\Schema;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Schema as GraphQLSchema;\n\nclass Schema\n{\n public static function build(): GraphQLSchema\n {\n // User type\n $userType = new ObjectType([\n 'name' => 'User',\n 'fields' => [\n 'id' => Type::int(),\n 'name' => Type::string(),\n 'email' => Type::string(),\n 'posts' => [\n 'type' => Type::listOf(function() use (&$postType) {\n return $postType;\n }),\n 'resolve' => function($user) {\n return \\App\\Resolvers\\QueryResolver::getPostsByUser($user['id']);\n }\n ]\n ]\n ]);\n\n // Post type\n $postType = new ObjectType([\n 'name' => 'Post',\n 'fields' => [\n 'id' => Type::int(),\n 'title' => Type::string(),\n 'content' => Type::string(),\n 'author' => [\n 'type' => $userType,\n 'resolve' => function($post) {\n return \\App\\Resolvers\\QueryResolver::getUserById($post['author_id']);\n }\n ]\n ]\n ]);\n\n // Root Query type\n $queryType = new ObjectType([\n 'name' => 'Query',\n 'fields' => [\n 'users' => [\n 'type' => Type::listOf($userType),\n 'resolve' => function() {\n return \\App\\Resolvers\\QueryResolver::getAllUsers();\n }\n ],\n 'user' => [\n 'type' => $userType,\n 'args' => [\n 'id' => Type::nonNull(Type::int())\n ]