GraphQL Resolvers Explained
# CHAPTER 10
GraphQL Resolvers Explained
1. Introduction
Up until now, we have focused heavily on the "frontend" of GraphQL—writing schemas, executing queries, and passing variables. But a schema is just an empty promise. How does the server actually fulfill that promise? Where does the data come from? The answer is Resolvers. Resolvers are the beating heart of a GraphQL server. In this chapter, we will learn what resolvers are, how they connect to your database (like MySQL), and how they resolve complex nested queries field by field.2. Learning Objectives
By the end of this chapter, you will be able to:- Define what a Resolver function is in GraphQL.
-
Understand the 4 standard arguments passed to every resolver (
$root,$args,$context,$info).
- Write resolver functions in PHP to fetch data from an array or database.
- Explain the execution flow of a GraphQL query on the server.
3. Beginner-Friendly Explanation
Imagine you are at a large library. You hand the librarian a list (the Query):- 1. Give me a book on Space.
- 2. Give me the author's name.
The Schema is the rulebook that says the library actually has books on space. The Resolver is the librarian physically walking to the shelf, finding the book, getting the data, and bringing it back to the desk.
Every single field in a GraphQL query has a dedicated Resolver (librarian) associated with it. When you ask for book, the Book Resolver goes to the database. When you ask for author inside the book, the Author Resolver looks at the book, sees the author ID, and goes to find the author's details.
4. Real-World Examples
-
Fetching from MySQL: A resolver for
getUser(id: 1)runs a SQL query:SELECT * FROM users WHERE id = 1, and returns the row.
-
Fetching from a Third-Party API: A resolver for
currentWeathermight use cURL to fetch data from the OpenWeatherMap REST API and return the JSON.
-
Calculated Fields: A resolver for
fullNamemight take thefirstNameandlastNamefrom the database, concatenate them, and return the combined string.
5. Detailed Code Examples
Let's look at how resolvers are written using PHP (viawebonyx/graphql-php).
The Scenario: A simple query fetching a user.
The PHP Resolvers:
6. The 4 Resolver Arguments
Every resolver function in the world (whether in PHP, Node, Python, etc.) receives four specific arguments:-
1.
$root(or$parent): The result of the previous resolver. If resolving theauthorof apost,$rootcontains thepostdata.
-
2.
$args: The arguments passed in the query (e.g.,id: 1).
-
3.
$context: An object shared across all resolvers. Used for storing the logged-in User's ID, database connections, or authentication tokens.
-
4.
$info: Advanced details about the query's execution state (rarely used by beginners).
7. Resolving Nested Queries
How does GraphQL handle nesting? Resolvers execute in a tree structure.8. Default Resolvers
You might wonder: "Do I have to write a resolver for every single string and integer field?" No. GraphQL libraries have "Default Resolvers." If youruser resolver returns a PHP associative array ['name' => 'Alice'], and the query asks for name, the default resolver automatically looks for the array key name and returns it. You only write custom resolvers for complex data fetching or relationships.
9. Best Practices
-
Keep Resolvers Thin: Do not put complex business logic inside the resolver. The resolver should only extract
$args, call a dedicated service class (e.g.,UserService->getUserById($id)), and return the result.
-
Use Context for Dependency Injection: Pass your PDO database connection and authenticated user session into the
$contextobject so all resolvers can access them without using global variables.
10. Common Mistakes
-
The N+1 Problem: This is the most famous GraphQL pitfall. If you query 100 posts, and each post resolves its author, the Author resolver might execute a SQL
SELECT100 times. We will discuss solving this (using DataLoaders) in later chapters.
-
Returning the Wrong Type: If the Schema says a field returns an
Int, but your resolver returns a string"42", GraphQL will throw an execution error.
11. Mini Exercises
- 1. Which resolver argument would you use to get the search term typed by a user?
- 2. Which resolver argument would you use to check if a user is logged in?
-
3.
What is the
$rootargument used for?
12. Coding Challenges
Challenge 1: Write a mock PHP resolver function for atotalUsers field. The resolver does not need any arguments. It should simply return the integer 150 representing a SELECT COUNT(*) from a database.
13. MCQs with Answers
What is the primary job of a Resolver in GraphQL?
Which argument in a resolver function contains the values passed by the client (like an ID or search term)?
Do you need to write a custom resolver function for a simple String field like username if it's already in the database array?
14. Interview Questions
-
Q: Explain the
$root(or parent) argument in a resolver. Give an example of when it is used.
-
Q: What kind of information should be stored in the
$contextobject?
-
Q: What happens if a resolver returns
nullfor a field marked asNon-Null (!)in the schema?
15. FAQs
Q: Can a resolver connect to multiple databases? A: Yes! A single GraphQL query can have one resolver fetching data from MySQL, another from MongoDB, and a third from an external REST API. The frontend client has no idea; it just sees one unified JSON response.Q: Are resolvers executed synchronously or asynchronously?
A: In Node.js, they are asynchronous (Promises). In standard PHP, execution is synchronous, though libraries like webonyx support asynchronous patterns using Promises for advanced use cases.
16. Summary
In this chapter, we lifted the hood on the GraphQL server to explore Resolvers. We learned that every field in a schema is backed by a resolver function. We explored the four core arguments passed to resolvers:$root for relational data, $args for client inputs, $context for global state (like auth/databases), and $info. Finally, we saw how GraphQL elegantly delegates data fetching by executing resolvers in a tree structure.