SQL database resolvers help connect GraphQL queries to your SQL database. They get the right data when someone asks for it.
SQL database resolvers in GraphQL
const resolvers = { Query: { getItems: async (parent, args, context) => { const [result] = await context.db.query('SELECT * FROM items WHERE category = ?', [args.category]); return result; } } };
Resolvers are functions that run when a GraphQL query or mutation is called.
They usually get arguments and use them to run SQL queries to fetch or change data.
const resolvers = { Query: { getUser: async (parent, args, context) => { const [user] = await context.db.query('SELECT * FROM users WHERE id = ?', [args.id]); return user; } } };
const resolvers = { Mutation: { addProduct: async (parent, args, context) => { await context.db.query('INSERT INTO products (name, price) VALUES (?, ?)', [args.name, args.price]); return { success: true }; } } };
This resolver gets all books by a specific author from the SQL database when the getBooks query is called.
const resolvers = { Query: { getBooks: async (parent, args, context) => { const [books] = await context.db.query('SELECT * FROM books WHERE author = ?', [args.author]); return books; } } };
Resolvers must return data in the shape expected by the GraphQL schema.
Use parameterized queries to avoid SQL injection risks.
Resolvers can be async to handle database calls that take time.
SQL database resolvers connect GraphQL queries to your SQL data.
They run SQL commands to get or change data based on query or mutation requests.
Resolvers help keep your data fetching organized and secure.
Practice
Solution
Step 1: Understand the purpose of resolvers
Resolvers are functions that connect GraphQL queries or mutations to the actual data source, here an SQL database.Step 2: Identify the role in data fetching and modification
Resolvers run SQL commands to get or change data as requested by the GraphQL operations.Final Answer:
To fetch or modify data in the SQL database based on GraphQL queries or mutations -> Option DQuick Check:
Resolvers connect queries to SQL data [OK]
- Confusing resolvers with schema definitions
- Thinking resolvers handle authentication
- Assuming resolvers format output only
getUser that fetches user data from an SQL database?Solution
Step 1: Identify the correct resolver structure for a query
Resolvers for queries are defined inside theQueryobject with function values.Step 2: Check the syntax for calling the database query
The resolver should be a function returning the result ofdb.querywith the SQL command string.Final Answer:
const resolvers = { Query: { getUser: () => db.query('SELECT * FROM users') } }; -> Option AQuick Check:
Query resolvers are functions inside Query object [OK]
- Placing query resolver inside Mutation
- Assigning SQL string directly instead of a function
- Defining resolver outside Query or Mutation objects
{ getUserById(id: 2) { name } } is executed?const resolvers = {
Query: {
getUserById: (_, args) => {
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Carol' }
];
return users.find(user => user.id === args.id);
}
}
};Solution
Step 1: Understand the resolver logic
The resolver searches the users array for an object withidequal toargs.id.Step 2: Match the query argument with the array data
The query requestsid: 2, so the resolver returns the user withid: 2, which is { id: 2, name: 'Bob' }.Final Answer:
{ "data": { "getUserById": { "name": "Bob" } } } -> Option BQuick Check:
Find user with id 2 = Bob [OK]
- Confusing id 2 with id 1 or 3
- Forgetting to access args.id
- Assuming resolver returns entire user object without filtering
const resolvers = {
Mutation: {
addUser: (parent, args) => {
db.query(`INSERT INTO users (name, email) VALUES (${args.name}, ${args.email})`);
return { success: true };
}
}
};Solution
Step 1: Analyze the SQL query construction
The SQL command uses string interpolation to insertargs.nameandargs.emaildirectly into the query string.Step 2: Identify security risk
This approach allows SQL injection attacks if user input contains malicious SQL code. Proper parameterization or prepared statements are needed.Final Answer:
SQL injection risk due to string interpolation without parameterization -> Option AQuick Check:
Unsafe string interpolation causes SQL injection [OK]
- Ignoring SQL injection vulnerability
- Thinking backticks cause errors
- Expecting mutation in Query object
users(id, active) and orders(id, user_id, total). Which resolver implementation correctly enforces this condition efficiently?Solution
Step 1: Understand the requirement
Fetch orders only if the user is active, combining the check and data fetch efficiently.Step 2: Evaluate each option
const resolvers = { Query: { userOrders: (_, args) => db.query(`SELECT * FROM orders WHERE user_id = ${args.userId} AND EXISTS (SELECT 1 FROM users WHERE id = ${args.userId} AND active = TRUE)`) } }; uses a single SQL query withEXISTSto check user active status and fetch orders in one call, which is efficient and correct.
const resolvers = { Query: { userOrders: (_, args) => { const user = db.query(`SELECT * FROM users WHERE id = ${args.userId}`); if (user.active) { return db.query(`SELECT * FROM orders WHERE user_id = ${args.userId}`); } else { return []; } } } }; fetches user first then orders separately, causing multiple queries and possible async issues.
const resolvers = { Query: { userOrders: (_, args) => db.query(`SELECT * FROM orders WHERE user_id = ${args.userId}`) } }; fetches orders without checking user active status.
const resolvers = { Query: { userOrders: (_, args) => db.query(`SELECT * FROM users WHERE id = ${args.userId} AND active = TRUE`) } }; fetches user data only, not orders.Final Answer:
const resolvers = { Query: { userOrders: (_, args) => db.query(`SELECT * FROM orders WHERE user_id = ${args.userId} AND EXISTS (SELECT 1 FROM users WHERE id = ${args.userId} AND active = TRUE)`) } }; -> Option CQuick Check:
Single query with EXISTS enforces condition efficiently [OK]
- Running multiple queries instead of one
- Not checking user active status before fetching orders
- Returning user data instead of orders
Ready to prove it?
Pass the test and this pattern moves unknown
