Building GraphQL APIs with PHP
# CHAPTER 18
Building GraphQL APIs with PHP
1. Introduction
Throughout this tutorial, we have looked at isolated snippets of PHP code. However, building a production-ready GraphQL API requires architectural organization. You cannot put your entire schema, hundreds of resolvers, and database connections into a singlegraphql.php file. In this chapter, we will learn how to structure a professional PHP GraphQL project, separate our concerns, manage routing, and integrate a database gracefully.
2. Learning Objectives
By the end of this chapter, you will be able to:- Architect a clean folder structure for a PHP GraphQL API.
- Separate Schema definitions, Types, and Resolvers into distinct files.
- Manage database connections and pass them via the Context object.
- Understand how modern PHP frameworks (like Laravel) handle GraphQL.
3. Beginner-Friendly Explanation
Imagine building a car. If you try to bolt the engine, the seats, the steering wheel, and the tires all together in one giant pile, it will be a mess. You won't be able to fix it if it breaks. Instead, you build modular components: an engine block, a chassis, an interior.In PHP, putting all your GraphQL logic in one file is the giant pile. Architecture is separating it out. We will create a folder just for "Types", a folder for "Database Models", and a central "Router" that simply accepts the HTTP request and delegates the work. This makes your code clean, readable, and highly maintainable.
4. Real-World Examples
- Custom PHP Backend: A lightweight API built without frameworks. It uses Composer for autoloading, PDO for MySQL connections, and strict directory structures for defining GraphQL Types.
- Laravel GraphQL (Lighthouse): In enterprise environments, developers use the Laravel framework alongside packages like Nuwave Lighthouse. Lighthouse allows you to write pure Schema SDL, and it automatically connects it to your Laravel Eloquent Database Models.
5. Recommended Folder Structure
For a core PHP project, a professional structure looks like this:
6. The Entry Point (index.php)
This file only does three things: handles HTTP, sets up Context, and executes.
7. Defining Types in Separate Files
Instead of defining types inline, we create classes.src/Types/UserType.php:
8. Database Integration
Resolvers should call dedicated Model classes, not run raw SQL directly inside the GraphQL configuration.In the Resolver:
9. Best Practices
-
Use PSR-4 Autoloading: Configure your
composer.jsonto automatically load your classes from the/srcdirectory. You should never userequire_oncemanually for your classes.
- Keep index.php Clean: Your entry point should be less than 50 lines of code. All complex logic should be abstracted into classes.
- Consider a Framework: While building from scratch is great for learning, if you are building a commercial application in PHP, use a framework like Laravel or Symfony with a dedicated GraphQL package to save hundreds of hours of setup.
10. Common Mistakes
-
Circular Dependencies: When
UserTyperequiresPostType, andPostTyperequiresUserType, PHP can get stuck in an infinite loop. Thewebonyxlibrary solves this by allowingfieldsto be defined as a closure (an anonymous functionfunction() { return [...] }) so they are evaluated lazily.
-
Database Logic inside Types: Never put PDO/MySQL connection credentials inside your Type files. Always pass them down via the
$context.
11. Mini Exercises
- 1. In the proposed folder structure, which folder contains the classes that directly interact with MySQL?
-
2.
Why is the database connection instantiated in
index.phpand passed into$context?
12. Coding Challenges
Challenge 1: Create the conceptualcomposer.json array needed to set up PSR-4 autoloading, mapping the namespace App\\ to the src/ directory.
13. MCQs with Answers
What is the primary purpose of separating a GraphQL API into modular folders (Types, Resolvers, Models)?
How should deeply nested Type definitions access the database connection?
What is a popular package used to implement GraphQL in the Laravel framework?
14. Interview Questions
- Q: Describe how you would organize the folder structure of a large-scale GraphQL application built in core PHP.
- Q: How do you solve circular dependency issues when defining GraphQL types that reference each other?
- Q: What is the benefit of using an established framework (like Lighthouse for Laravel) over building a GraphQL server from scratch?
15. FAQs
Q: Can I use an ORM like Doctrine or Eloquent with a standalone PHP GraphQL setup? A: Absolutely. Your resolvers don't care where the data comes from. You can easily boot up Eloquent ORM in yourindex.php and use it inside your resolvers.
16. Summary
In this chapter, we transitioned from basic scripting to professional software architecture. We learned how to organize a PHP GraphQL project into modular components: a single HTTP entry point (index.php), isolated Type definitions, dedicated Resolver functions, and Database models. We also discussed how the $context object is the critical glue that passes global dependencies (like the database connection) down into the deeply nested resolver tree.