📖 Scenario: You are building a simple user management system where users have roles like admin, editor, and viewer. Each role has different permissions to access user data.
🎯 Goal: Create a GraphQL schema that defines users with roles and implements role-based access control to restrict data access based on the user's role.
📋 What You'll Learn
Define a User type with fields id, name, and role.
Create a query users that returns a list of users.
Add a variable currentUserRole to simulate the role of the user making the request.
Implement role-based access control so that only admin users can see all users, editor users can see users with role viewer, and viewer users can only see their own data.
💡 Why This Matters
🌍 Real World
Role-based access control is essential in real-world applications to protect sensitive data and ensure users only see what they are allowed to.
💼 Career
Understanding how to implement role-based access control in GraphQL is valuable for backend developers working on secure APIs.
Progress0 / 4 steps
1
Define the User type and initial data
Create a GraphQL type called User with fields id (ID!), name (String!), and role (String!). Then create a list called users with these exact entries: { id: "1", name: "Alice", role: "admin" }, { id: "2", name: "Bob", role: "editor" }, { id: "3", name: "Charlie", role: "viewer" }.
GraphQL
Hint
Start by defining the User type with the required fields. Then create the users list with the exact user objects.
2
Add currentUserRole variable
Add a variable called currentUserRole and set it to the string "editor" to simulate the role of the user making the request.
GraphQL
Hint
Just add a constant variable named currentUserRole and assign it the string "editor".
3
Create users query with role-based filtering
Create a query called users that returns a list of User. Implement role-based access control inside the resolver function so that: if currentUserRole is "admin", return all users; if currentUserRole is "editor", return only users with role "viewer"; if currentUserRole is "viewer", return only the user with id"3".
GraphQL
Hint
Use if statements to check currentUserRole and return filtered user lists accordingly.
4
Add GraphQL schema with Query type
Add a Query type to the GraphQL schema with a field users that returns a list of User. Combine all previous code into a complete schema and resolver setup.
GraphQL
Hint
Define the Query type with a users field that returns a list of User objects.
Practice
(1/5)
1. What is the main purpose of role-based access control (RBAC) in GraphQL APIs?
easy
A. To format the response data
B. To speed up query execution
C. To restrict data access based on user roles
D. To cache query results
Solution
Step 1: Understand RBAC concept
RBAC limits what data users can access depending on their assigned roles.
Step 2: Identify RBAC purpose in GraphQL
In GraphQL, RBAC ensures users only see or modify data allowed by their role.
Final Answer:
To restrict data access based on user roles -> Option C
Quick Check:
RBAC = restrict access by role [OK]
Hint: RBAC controls who can see or change data [OK]
Common Mistakes:
Confusing RBAC with performance optimization
Thinking RBAC formats data output
Assuming RBAC caches data
2. Which of the following is the correct way to apply a role-based directive in a GraphQL schema to restrict a query to admins only?
easy
A. type Query { users: [User] @hasRole(role: "admin") }
B. type Query { users: [User] @roleCheck("admin") }
C. type Query { users: [User] @auth(role: "admin") }
D. type Query { users: [User] @access(role = admin) }
Solution
Step 1: Identify correct directive syntax
The standard directive for role checks is @hasRole with a role argument as a string.
Step 2: Match syntax to options
type Query { users: [User] @hasRole(role: "admin") } uses @hasRole(role: "admin"), which is the correct syntax.
Final Answer:
type Query { users: [User] @hasRole(role: "admin") } -> Option A
Quick Check:
@hasRole(role: "admin") syntax correct [OK]
Hint: Look for @hasRole with role as string argument [OK]
Common Mistakes:
Using incorrect directive names like @auth or @roleCheck
Missing quotes around role name
Using = instead of : in directive arguments
3. Given this GraphQL query protected by @hasRole(role: "editor"), what will happen if a user with role "viewer" tries to run it?
query { editArticle(id: "123") { title content } }
medium
A. The query returns an authorization error
B. The query returns empty data with no error
C. The query returns the article data as usual
D. The query causes a server crash
Solution
Step 1: Understand role restriction effect
@hasRole(role: "editor") restricts access to users with the editor role only.
Step 2: Check user role against required role
User has role "viewer", which does not match "editor", so access is denied.
Final Answer:
The query returns an authorization error -> Option A
Quick Check:
Role mismatch = authorization error [OK]
Hint: Role mismatch causes authorization error [OK]
Common Mistakes:
Assuming query returns data anyway
Thinking query returns empty data silently
Believing server crashes on role denial
4. You wrote this schema directive to restrict a mutation to admins:
type Mutation { deleteUser(id: ID!): Boolean @hasRole(role: admin) }
Why does this cause a syntax error?
medium
A. The directive name @hasRole is invalid
B. ID! is not a valid type
C. Mutation type cannot have directives
D. The role value admin is missing quotes
Solution
Step 1: Check directive argument syntax
Directive arguments require string values in quotes, e.g., role: "admin".
Step 2: Identify missing quotes error
Here, role: admin lacks quotes, causing a syntax error.
Final Answer:
The role value admin is missing quotes -> Option D
Quick Check:
Directive string args need quotes [OK]
Hint: Always put role names in quotes in directives [OK]
Common Mistakes:
Thinking directive names are wrong
Believing directives can't be on mutations
Misunderstanding ID! type syntax
5. You want to allow only users with roles "admin" or "manager" to update product prices. Which schema directive setup correctly enforces this in GraphQL?
hard
A. type Mutation { updatePrice(id: ID!, price: Float): Product @hasAnyRole(roles: ["admin", "manager"]) }
B. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) }
C. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: "admin") @hasRole(role: "manager") }
D. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(roles: "admin,manager") }
Solution
Step 1: Understand multi-role directive syntax
@hasRole accepts an array of roles to allow multiple roles access.
Step 2: Evaluate options for correct syntax
type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) } uses @hasRole(role: ["admin", "manager"]), which correctly passes an array of roles.
Step 3: Identify incorrect options
type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(roles: "admin,manager") } passes a string, not an array; C uses multiple directives which may not combine logically; A uses a non-standard directive @hasAnyRole.
Final Answer:
type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) } -> Option B
Quick Check:
Array of roles in @hasRole = correct [OK]
Hint: Use array syntax for multiple roles in @hasRole [OK]
Common Mistakes:
Passing roles as comma string instead of array
Using multiple @hasRole directives expecting OR logic
Using non-standard directive names
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.