Top GraphQL Interview Questions for Freshers
Key Takeaways
In this article, we will learn about:
- Basic GraphQL concepts like schema, queries, mutations, resolvers, types, fields, and arguments.
- How GraphQL helps clients request only the data they need.
- Intermediate GraphQL topics like variables, fragments, aliases, nested data, introspection, Apollo Client, and Apollo Server.
- Advanced GraphQL concepts like authentication, authorization, caching, pagination, DataLoader, and query optimization.
- Scenario-based GraphQL interview questions related to slow queries, API security, schema design, and REST vs GraphQL
GraphQL is becoming an important API skill for freshers preparing for frontend, backend, full-stack, API developer, and web development roles.
Its enterprise adoption has reportedly surged by 340% since 2023, with companies like GitHub, Shopify, Netflix, Airbnb, Pinterest, and PayPal using GraphQL in production. Since GraphQL helps clients request only the data they need, it is widely used for building flexible and efficient APIs.
This article covers basic, intermediate, advanced, and conceptual GraphQL interview questions and answers for interview preparation.
Basic GraphQL Interview Questions
Here are the basic GraphQL interview questions freshers should prepare before moving to advanced API concepts.
These questions cover the foundation of GraphQL, including schemas, queries, mutations, resolvers, fields, types, and how GraphQL differs from REST APIs.
1. What is GraphQL?
GraphQL is a query language for APIs and a runtime for fetching data from a server. It allows the client to request exactly the data it needs instead of receiving a fixed response from the server.
In GraphQL, the frontend sends a query that clearly mentions the required fields, and the server returns only those fields.
Example:
{
user {
name
}
}
Response:
Here, the client requested only name and email, so the server returned only those two fields.
GraphQL is commonly used in frontend, backend, full-stack, mobile app, and API development because it makes data fetching more flexible and efficient.
2. Why is GraphQL used?
GraphQL is used to make API communication more flexible, efficient, and client-friendly. In traditional REST APIs, the server decides what data is returned from each endpoint. In GraphQL, the client decides what data it wants.
GraphQL is mainly used to solve problems like:
- Over-fetching: Getting more data than required.
- Under-fetching: Getting less data than required and calling multiple APIs.
- Multiple endpoint dependency: Using many REST endpoints for related data.
- Frontend flexibility: Allowing different clients like web apps and mobile apps to request different data.
Example:
A mobile app may need only:
{
user {
name
}
}
But a web dashboard may need:
{
user {
name
orders {
id
amount
}
}
}
Both clients can use the same GraphQL API but request different data based on their needs.
3. What is a GraphQL schema?
A GraphQL schema defines the structure of the API. It describes what data can be requested, what operations are allowed, and what type of data each field returns.
The schema acts like a contract between the client and the server. It tells the client what queries, mutations, types, and fields are available.
Example:
type User {
id: ID
name: String
email: String
}
type Query {
user: User
}
In this schema:
- User is a GraphQL type.
- id, name, and email are fields.
- Query defines what data the client can request.
- user returns data of type User.
A schema is important because GraphQL APIs are strongly typed. This means every field has a defined data type, which makes the API easier to understand, test, and maintain.
4. What is a GraphQL query?
A GraphQL query is used to read or fetch data from the server. It is similar to a GET request in REST, but it gives the client more control over the response structure.
The client writes a query by selecting only the fields it needs.
Example:
{
student {
name
course
}
}
Response:
{
“data”: {
“student”: {
“name”: “Priya”,
“course”: “Full Stack Development”
}
}
}
In this example, the query asks for the student’s name and course. The server returns only those fields.
A GraphQL query is useful when the frontend wants to display specific data without loading unnecessary information from the backend.
5. What is a GraphQL mutation?
A GraphQL mutation is used to modify data on the server. It is used for operations such as creating, updating, or deleting data.
In REST, we commonly use POST, PUT, PATCH, or DELETE for these actions. In GraphQL, mutations are used for all write operations.
Example:
This mutation creates a new user and returns the user’s id, name, and email.
Mutations are important because they allow the client to clearly define:
- What action should be performed.
- What input data is being sent.
- What fields should be returned after the operation.
6. What is a GraphQL resolver?
A resolver is a function that contains the logic for fetching or modifying data for a specific field in a GraphQL schema.
The schema defines what data is available, but the resolver defines how that data is actually fetched.
Example schema:
type Query {
user: User
}
Example resolver:
const resolvers = {
Query: {
user: () => {
return {
id: “1”,
name: “Karthik”,
email: “[email protected]”
};
}
}
};
Here, when the client requests the user field, the resolver function runs and returns the user data.
Resolvers can fetch data from:
- Databases
- REST APIs
- Microservices
- Files
- Third-party APIs
- In-memory objects
In simple words, the resolver connects the GraphQL query with the actual data source.
7. What is a GraphQL type?
A GraphQL type defines the shape of data in a GraphQL schema. It tells what fields an object can have and what kind of values those fields return.
Example:
type Product {
id: ID
name: String
price: Float
inStock: Boolean
}
Here, Product is a GraphQL type.
It has four fields:
- id returns an ID
- name returns a String
- price returns a Float
- inStock returns a Boolean
GraphQL types help make the API predictable because the client knows exactly what kind of data to expect.
Common GraphQL types include:
- String
- Int
- Float
- Boolean
- ID
- Object types
- List types
- Enum types
- Input types
8. What are fields in GraphQL?
Fields are the individual pieces of data inside a GraphQL type. When writing a query, the client selects fields to specify what data it wants from the server.
Example schema:
type Employee {
id: ID
name: String
department: String
salary: Float
}
Here, id, name, department, and salary are fields of the Employee type.
Example query:
{
employee {
name
department
}
}
In this query, the client is requesting only two fields: name and department.
Fields are one of the most important parts of GraphQL because they allow clients to fetch only the required data.
9. What is the difference between GraphQL and REST?
GraphQL and REST are both used to build APIs, but they work differently.
REST usually uses multiple endpoints for different resources, while GraphQL usually uses a single endpoint where the client sends queries to request the required data.
| Feature | REST | GraphQL |
| API structure | Multiple endpoints | Usually a single endpoint |
| Data fetching | Server decides response structure | Client decides response structure |
| Over-fetching | Common problem | Reduced |
| Under-fetching | Common problem | Reduced |
| Request type | Uses HTTP methods like GET, POST, PUT, DELETE | Uses queries and mutations |
| Response format | Fixed by endpoint | Based on requested fields |
| Best suited for | Simple resource-based APIs | Flexible and complex data requirements |
REST example:
GET /users/1
GET /users/1/orders
GraphQL example:
{
user(id: 1) {
name
orders {
id
amount
}
}
}
In REST, multiple API calls may be needed to fetch related data. In GraphQL, the same data can often be fetched using a single query.
10. What is GraphQL Playground?
GraphQL Playground is an interactive tool used to test and explore GraphQL APIs. It allows developers to write queries, mutations, and subscriptions and see the response directly.
It is similar to Postman, but specifically designed for GraphQL APIs.
With GraphQL Playground, developers can:
- Write and test GraphQL queries.
- Test mutations.
- View schema documentation.
- Check available types and fields.
- Pass variables.
- Debug API responses.
Example query in GraphQL Playground:
{
users {
id
name
}
}
The tool sends this query to the GraphQL server and displays the response.
GraphQL Playground is useful for freshers because it helps them understand how queries are written, how schemas work, and how data is returned from a GraphQL API.
11. What is an endpoint in GraphQL?
An endpoint is the URL through which the client communicates with the server.
In REST, there are usually multiple endpoints for different resources.
Example REST endpoints:
/users
/users/1
/products
/orders
In GraphQL, there is usually a single endpoint, commonly:
/graphql
The client sends different queries or mutations to this same endpoint.
Example:
POST /graphql
Request body:
{
user(id: 1) {
name
}
}
So, in GraphQL, the endpoint remains the same, but the query changes based on the data required by the client.
| REST Endpoint Example | GraphQL Endpoint Example |
| /users | /graphql |
| /users/1 | /graphql |
| /users/1/orders | /graphql |
| /products | /graphql |
This single-endpoint approach is one reason GraphQL is flexible for modern frontend and mobile applications.
12. What is a scalar type in GraphQL?
A scalar type is a basic data type in GraphQL that represents a single value. Scalar types are used to define the type of data returned by a field.
Common built-in scalar types in GraphQL are:
| Scalar Type | Meaning | Example |
| String | Text value | “Amit” |
| Int | Integer number | 25 |
| Float | Decimal number | 99.50 |
| Boolean | True or false value | true |
| ID | Unique identifier | “101” |
Example:
type Student {
id: ID
name: String
age: Int
percentage: Float
isActive: Boolean
}
Here:
- id is an ID
- name is a String
- age is an Int
- percentage is a Float
- isActive is a Boolean
Scalar types are important because they make the GraphQL schema strongly typed and predictable.
13. What are arguments in GraphQL?
Arguments are values passed to a GraphQL field to filter, identify, or customize the data returned by the server.
They are similar to parameters in a function.
Example:
{
user(id: 5) {
name
}
}
Here, id: 5 is an argument. It tells the server to return the user whose ID is 5.
Arguments can be used for:
- Fetching data by ID
- Filtering records
- Sorting data
- Limiting results
- Searching data
Example with filtering:
{
products(category: “laptop”) {
name
price
}
}
Here, the category argument is used to fetch only laptop products.
Arguments make GraphQL queries more dynamic and useful because the client can request specific data instead of fetching everything.
14. What is the role of the client in GraphQL?
In GraphQL, the client is responsible for requesting the exact data it needs from the server.
The client can be a:
- Web application
- Mobile application
- Frontend framework like React, Angular, or Vue
- API testing tool like GraphQL Playground or Apollo Studio
The client writes a GraphQL query or mutation and sends it to the GraphQL server.
Example client query:
{
course(id: 10) {
title
duration
}
}
In this case, the client is asking for only the title and duration of a course.
The client’s main responsibilities are:
- Sending queries to fetch data.
- Sending mutations to create, update, or delete data.
- Passing arguments and variables.
- Selecting only required fields.
- Handling the response returned by the server.
- Displaying the data in the UI.
GraphQL gives more control to the client because the client decides the response structure.
15. What is the role of the server in GraphQL?
In GraphQL, the server is responsible for receiving the client’s query, validating it against the schema, executing the required resolvers, and returning the response.
The server contains the main backend logic of the GraphQL API.
The server’s responsibilities include:
- Defining the GraphQL schema.
- Creating queries and mutations.
- Writing resolver functions.
- Validating client requests.
- Fetching data from databases or external APIs.
- Applying authentication and authorization.
- Returning data in the same structure requested by the client.
- Sending errors if the request is invalid.
Example:
Client query:
{
user(id: 1) {
name
}
}
Server-side flow:
- The server receives the query.
- It checks whether user, name, and email exist in the schema.
- It calls the resolver for user.
- The resolver fetches user data from the database.
- The server returns only name and email.
Response:
So, the client decides what data it wants, and the server decides how to fetch and return that data correctly.
Intermediate GraphQL Interview Questions
Once you understand the basics, these intermediate GraphQL interview questions and answers help you build practical knowledge.
This section focuses on real implementation concepts like variables, fragments, aliases, nested data, error handling, introspection, Apollo Client, Apollo Server, and how GraphQL connects with databases.
1. How does GraphQL solve over-fetching and under-fetching?
GraphQL solves over-fetching by allowing the client to request only the fields it needs. For example, if the frontend needs only a user’s name and email, it does not have to receive the full user profile.
GraphQL also solves under-fetching by allowing related data to be fetched in a single query. In REST, you may need separate API calls for user details, orders, and payments. In GraphQL, all required data can be requested together.
Example:
{
user(id: 1) {
name
orders {
id
amount
}
}
}
This makes GraphQL useful for dashboards, mobile apps, and complex frontend screens.
2. How do queries and mutations differ?
Queries and mutations are two main operation types in GraphQL.
| Feature | Query | Mutation |
| Purpose | Fetch data | Modify data |
| Similar REST action | GET | POST, PUT, PATCH, DELETE |
| Changes server data? | No | Yes |
| Example use case | Get user details | Create or update user |
Query example:
{
user(id: 1) {
name
}
}
Mutation example:
mutation {
updateUser(id: 1, name: “Ravi”) {
id
name
}
}
A query is used for reading data, while a mutation is used when data needs to be created, updated, or deleted.
3. How do resolvers work in GraphQL?
Resolvers are functions that execute when a GraphQL field is requested. The schema defines what fields are available, and resolvers define how to fetch the data for those fields.
When a client sends a query, GraphQL checks the schema and then calls the matching resolver.
Example:
const resolvers = {
Query: {
user: (parent, args) => {
return getUserById(args.id);
}
}
};
Here, when the query requests user(id: 1), the resolver receives the id through args and fetches the user data.
Resolvers can fetch data from databases, REST APIs, microservices, or other data sources.
4. What are variables in GraphQL?
Variables in GraphQL are used to pass dynamic values into a query or mutation. They help avoid hardcoding values directly inside the query.
Example:
query GetUser($id: ID!) {
user(id: $id) {
name
}
}
Variables:
{
“id”: “1”
}
Here, $id is a variable. The actual value is passed separately.
Variables are useful because they make queries:
- Reusable
- Cleaner
- Easier to test
- Safer for dynamic user input
They are commonly used in frontend applications where values like user ID, product ID, filters, or search keywords change based on user actions.
5. What are fragments in GraphQL?
Fragments are reusable sets of fields in GraphQL. They help avoid repeating the same fields in multiple queries.
Example:
fragment UserDetails on User {
id
name
}
This fragment can be reused inside a query:
{
user(id: 1) {
…UserDetails
}
}
Fragments are useful when the same fields are needed in different places, such as user cards, profile pages, and dashboard views.
They improve:
- Code reuse
- Query readability
- Maintainability
- Consistency in requested fields
In real projects, fragments are commonly used with Apollo Client and React components.
6. What is aliasing in GraphQL?
Aliasing allows the client to rename the result field in a GraphQL response. It is useful when the same field needs to be queried multiple times with different arguments.
Example:
{
firstUser: user(id: 1) {
name
}
secondUser: user(id: 2) {
name
}
}
Response:
{
“data”: {
“firstUser”: {
“name”: “Amit”
},
“secondUser”: {
“name”: “Neha”
}
}
}
Without aliases, both fields would have the same name user, which can create a conflict. Aliasing helps make the response clear and meaningful.
7. How is error handling done in GraphQL?
GraphQL responses can contain both data and errors. If part of the query succeeds and another part fails, GraphQL can still return partial data along with error details.
Example response:
{
“data”: {
“user”: null
},
“errors”: [
{
“message”: “User not found”,
“path”: [“user”]
}
]
}
Errors are usually handled in resolvers by throwing exceptions or returning proper error messages.
Common GraphQL errors include:
- Validation errors
- Authentication errors
- Authorization errors
- Database errors
- Missing or invalid arguments
In production, sensitive internal details should not be exposed in error messages.
8. How does GraphQL handle nested data?
GraphQL handles nested data by allowing the client to request related objects inside the same query. This is one of its biggest advantages over traditional REST APIs.
Example:
{
user(id: 1) {
name
orders {
id
amount
product {
name
}
}
}
}
Here, the query fetches a user, their orders, and product details inside each order.
GraphQL executes the required resolvers for each level of nesting. This makes it easy to fetch complex relational data, but very deep nested queries should be controlled using depth limiting or query complexity checks.
9. What is introspection in GraphQL?
Introspection is a GraphQL feature that allows clients and tools to query the schema itself. It helps developers understand what types, fields, queries, mutations, and arguments are available in the API.
Tools like GraphQL Playground, Apollo Studio, and GraphiQL use introspection to show API documentation automatically.
For example, introspection can show:
- Available queries
- Available mutations
- Object types
- Field names
- Argument types
- Return types
Introspection is very useful during development. However, in production, some teams disable or restrict it for security reasons, especially when the API should not expose internal schema details publicly.
10. How do you pass arguments in a GraphQL query?
Arguments are passed inside parentheses after a field name. They are used to filter, search, sort, limit, or fetch specific data.
Example:
{
user(id: 10) {
name
}
}
Here, id: 10 is an argument passed to the user field.
Arguments can also be used for filtering:
{
products(category: “mobile”, limit: 5) {
name
price
}
}
In the resolver, these arguments are usually accessed through the args parameter.
Example:
user: (parent, args) => getUserById(args.id)
Arguments make GraphQL queries dynamic and practical for real applications.
11. How do you structure a GraphQL schema?
A GraphQL schema is usually structured by defining types, queries, mutations, and input types clearly.
Example:
type User {
id: ID!
name: String!
email: String!
}
type Query {
user(id: ID!): User
users: [User]
}
type Mutation {
createUser(input: CreateUserInput!): User
}
input CreateUserInput {
name: String!
email: String!
}
A good schema should be:
- Clear and readable
- Strongly typed
- Easy to extend
- Designed around business entities
- Properly separated into queries and mutations
For larger projects, schemas are often split into modules like User, Product, Order, and Payment.
12. What is the difference between schema and resolver?
A schema defines what the GraphQL API can do, while resolvers define how the API actually performs those actions.
| Feature | Schema | Resolver |
| Meaning | API structure | Function logic |
| Defines | Types, fields, queries, mutations | How data is fetched or modified |
| Written as | GraphQL type definitions | JavaScript/Node.js or backend code |
| Example | user(id: ID!): User | getUserById(args.id) |
Schema example:
type Query {
user(id: ID!): User
}
Resolver example:
user: (parent, args) => getUserById(args.id)
In simple terms, the schema is the API contract, and the resolver is the implementation logic.
13. How does GraphQL work with databases?
GraphQL does not directly depend on any specific database. It works as an API layer between the client and the data source.
The flow usually works like this:
- Client sends a GraphQL query.
- Server validates the query against the schema.
- Resolver function is executed.
- Resolver fetches data from a database.
- Server returns the response in the requested structure.
GraphQL can work with:
- SQL databases like MySQL and PostgreSQL
- NoSQL databases like MongoDB
- ORMs like Prisma, Sequelize, or TypeORM
- REST APIs and microservices
GraphQL itself does not store data. It only provides a flexible way to request and return data.
14. What is Apollo Client?
Apollo Client is a popular GraphQL client library used in frontend applications. It helps the frontend send queries and mutations to a GraphQL server and manage the returned data.
It is commonly used with React, Angular, Vue, and mobile applications.
Apollo Client helps with:
- Sending GraphQL queries
- Sending mutations
- Managing loading and error states
- Caching API responses
- Updating UI after data changes
- Working with fragments and variables
Example use case:
A React application can use Apollo Client to fetch user profile data and automatically update the UI when the data changes.
Apollo Client is useful because it reduces manual API handling work in frontend applications.
15. What is Apollo Server?
Apollo Server is a popular open-source GraphQL server used to build GraphQL APIs. It helps developers define schemas, write resolvers, and expose a GraphQL endpoint.
It is commonly used with Node.js and can connect to databases, REST APIs, and microservices.
Apollo Server is used for:
- Creating GraphQL APIs
- Defining type definitions
- Writing resolver functions
- Handling queries and mutations
- Managing context for authentication
- Connecting GraphQL with databases
Basic structure:
const server = new ApolloServer({
typeDefs,
resolvers
});
In simple terms, Apollo Server is used on the backend, while Apollo Client is used on the frontend to communicate with a GraphQL API.
Advanced GraphQL Interview Questions
These advanced GraphQL interview questions are useful for freshers who want to stand out in technical interviews.
The questions cover performance, security, caching, pagination, subscriptions, query optimization, DataLoader, authentication, authorization, and other production-level GraphQL concepts.
1. What is the N+1 problem in GraphQL?
The N+1 problem happens when GraphQL executes too many database queries while resolving nested data.
For example, suppose a query fetches 10 users and each user’s orders:
{
users {
name
orders {
id
amount
}
}
}
A poor resolver may first run 1 query to fetch all users, then run 10 separate queries to fetch orders for each user.
So, total queries become:
1 query for users + 10 queries for orders = 11 queries
This is called the N+1 problem because for N users, the server makes N additional queries.
It can slow down GraphQL APIs badly, especially when nested fields are used. This issue is common in GraphQL because each field has its own resolver, and nested resolvers may repeatedly hit the database.
2. How can DataLoader help in GraphQL?
DataLoader helps solve the N+1 problem by batching and caching database requests.
Instead of calling the database separately for each user’s orders, DataLoader collects multiple requests and sends them as one batch query.
Without DataLoader:
getOrders(userId: 1)
getOrders(userId: 2)
getOrders(userId: 3)
With DataLoader:
getOrdersByUserIds([1, 2, 3])
This reduces multiple database calls into a single optimized query.
DataLoader mainly helps in two ways:
- Batching: Combines multiple similar requests into one query.
- Caching: Stores already fetched data during the same request cycle.
For example, if the same user data is needed multiple times in one GraphQL request, DataLoader can return it from cache instead of hitting the database again.
3. How does authentication work in GraphQL APIs?
Authentication is the process of verifying who the user is. In GraphQL APIs, authentication usually happens before executing resolvers.
A common approach is to send a token, such as a JWT, in the request header.
Example:
Authorization: Bearer <token>
The GraphQL server verifies the token and adds the authenticated user details to the request context.
Example flow:
- User logs in with email and password.
- Server returns a JWT token.
- Client sends the token with every GraphQL request.
- Server verifies the token.
- User details are added to context.
- Resolvers use context.user to identify the logged-in user.
Example resolver:
profile: (parent, args, context) => {
if (!context.user) {
throw new Error(“Not authenticated”);
}
return getUserById(context.user.id);
}
Authentication confirms the identity of the user.
4. How does authorization work in GraphQL?
Authorization decides what an authenticated user is allowed to access or perform. Authentication checks who the user is, while authorization checks what permissions the user has.
For example, a user may be logged in, but they should not be allowed to access another user’s orders.
Example:
order: async (parent, args, context) => {
if (!context.user) {
throw new Error(“Not authenticated”);
}
const order = await getOrderById(args.id);
if (order.userId !== context.user.id) {
throw new Error(“Not authorized”);
}
return order;
}
Authorization can be handled at:
- Resolver level
- Field level
- Schema directive level
- Middleware level
- Service/business logic level
| Feature | Authentication | Authorization |
| Meaning | Verifies user identity | Verifies user permission |
| Question answered | Who are you? | What can you access? |
| Example | Login with JWT token | User can access only their own orders |
| Happens when | Before or during request processing | During resolver/business logic execution |
| Failure message | Not authenticated | Not authorized |
5. How do you optimize GraphQL queries?
GraphQL queries can be optimized by reducing unnecessary database calls, controlling query size, and improving resolver performance.
Common GraphQL optimization techniques include:
- Use DataLoader to avoid the N+1 problem.
- Add pagination for large lists.
- Use query depth limiting to prevent deeply nested queries.
- Use query complexity analysis to block expensive queries.
- Select only required fields from the database.
- Cache frequently requested data.
- Avoid heavy logic inside resolvers.
- Use indexes in the database for filtered fields.
- Monitor slow queries using logs and tracing tools.
For example, if a query fetches thousands of records without pagination, it should be redesigned to fetch limited results using arguments like limit, offset, first, or after.
Optimization is important because GraphQL gives flexibility to clients, but the server must still protect performance.
6. What are subscriptions in GraphQL?
Subscriptions are GraphQL operations used to receive real-time updates from the server. Queries are used to read data, mutations are used to modify data, and subscriptions are used to listen for live changes.
Subscriptions are commonly used for:
- Chat messages
- Live notifications
- Real-time dashboards
- Stock price updates
- Order status updates
- Live sports scores
Example:
subscription {
messageAdded {
id
text
sender
}
}
When a new message is added, the server automatically pushes the update to subscribed clients.
Subscriptions usually work using WebSockets because the client and server need a continuous connection.
| Feature | Query | Mutation | Subscription |
| Purpose | Fetch data | Modify data | Receive real-time updates |
| Data flow | Client asks, server responds | Client sends change, server responds | Server pushes updates |
| Similar REST concept | GET | POST/PUT/DELETE | WebSocket/event stream |
| Example | Get profile | Create order | New message notification |
7. How does GraphQL support real-time updates?
GraphQL supports real-time updates mainly through subscriptions. A client subscribes to a specific event, and whenever that event occurs on the server, the server pushes updated data to the client.
For example, in a food delivery app, the frontend can subscribe to order status updates.
subscription {
orderStatusUpdated(orderId: “101”) {
status
updatedAt
}
}
When the order status changes from PREPARING to OUT_FOR_DELIVERY, the client receives the update immediately.
Real-time GraphQL commonly uses:
- WebSockets
- Pub/Sub systems
- Event emitters
- Message brokers like Redis Pub/Sub, Kafka, or RabbitMQ
The basic flow is:
Client subscribes → Server listens for event → Event occurs → Server pushes data to client
This is useful when the UI must update without refreshing the page.
8. What is query depth limiting?
Query depth limiting is a technique used to restrict how deeply nested a GraphQL query can be.
GraphQL allows clients to request nested data, but very deep queries can become expensive for the server.
Example of a deep query:
{
user {
posts {
comments {
replies {
user {
posts {
comments {
text
}
}
}
}
}
}
}
}
This kind of query can create heavy database load.
Query depth limiting sets a maximum allowed nesting depth.
For example:
Maximum query depth = 5
If a client sends a query deeper than 5 levels, the server rejects it.
This protects the API from:
- Expensive nested queries
- Accidental performance issues
- Malicious query abuse
- Slow API responses
Depth limiting is an important security and performance practice in GraphQL APIs.
9. What is query complexity analysis?
Query complexity analysis is used to estimate how expensive a GraphQL query is before executing it.
Depth limiting only checks how deep a query is, but complexity analysis checks how costly the query can be based on fields, lists, nested objects, and custom weights.
For example:
{
users(first: 1000) {
posts {
comments {
text
}
}
}
}
This query may not look extremely deep, but it can be very expensive because it asks for 1000 users, their posts, and comments.
In query complexity analysis, each field can be assigned a cost.
Example:
user = 1 point
posts = 5 points
comments = 10 points
If the total query cost exceeds the allowed limit, the server rejects the query.
This helps prevent expensive requests from affecting server performance.
10. How do you prevent expensive GraphQL queries?
Expensive GraphQL queries can be prevented using a combination of validation, limits, and performance controls.
Important methods include:
- Add query depth limits to block deeply nested queries.
- Add query complexity limits to block high-cost queries.
- Use pagination for lists.
- Set maximum values for arguments like limit or first.
- Use timeouts for long-running requests.
- Apply rate limiting per user or IP.
- Disable or restrict introspection in production if needed.
- Use persisted queries for trusted operations.
- Optimize resolvers and database queries.
- Use DataLoader to prevent N+1 database calls.
- Add authentication and authorization checks.
For example, instead of allowing this:
users(limit: 100000)
Restrict it to:
users(limit: 50)
This protects the backend from heavy data fetching and improves API stability.
11. How does caching work in GraphQL?
Caching in GraphQL is different from REST because GraphQL usually uses a single endpoint, such as /graphql. In REST, caching is easier at the URL level because each endpoint represents a resource.
In GraphQL, caching can happen at different levels:
- Client-side caching: Apollo Client or Relay caches query results.
- Resolver-level caching: Frequently used resolver results are cached.
- Database caching: Database query results are cached.
- CDN/API caching: Possible with persisted queries or GET-based queries.
- Object-level caching: Data is cached by object ID and type.
For example, Apollo Client can cache a User object using its id and reuse it in different UI components.
| Feature | REST Caching | GraphQL Caching |
| Endpoint pattern | Multiple resource URLs | Usually single endpoint |
| Cache key | URL-based | Query-based or object-based |
| Simpler HTTP caching | Easier | More complex |
| Client cache | Optional | Commonly used |
| Common tools | Browser cache, CDN | Apollo Client, Relay, resolver cache |
| Challenge | Less flexible response | Dynamic query structure |
GraphQL caching requires a more planned strategy because different queries can request different fields from the same object.
12. What is persisted query in GraphQL?
A persisted query is a GraphQL query that is stored on the server or known in advance. Instead of sending the full query every time, the client sends a unique ID or hash of the query.
Normal request:
{
user(id: 1) {
name
orders {
id
amount
}
}
}
Persisted query request:
{
“queryId”: “abc123”,
“variables”: {
“id”: “1”
}
}
The server uses queryId to find and execute the stored query.
Persisted queries are useful because they:
- Reduce request payload size
- Improve performance
- Allow better caching
- Prevent unknown or unapproved queries
- Improve security by allowing only trusted queries
They are commonly used in production GraphQL systems where performance and security are important.
13. How do you handle pagination in GraphQL?
Pagination in GraphQL is used to fetch large lists in smaller parts instead of loading all records at once.
For example, instead of fetching 10,000 products together, the client can request only 10 or 20 products per page.
Common pagination approaches are:
- Offset-based pagination
- Cursor-based pagination
Offset pagination uses values like limit and offset.
{
products(limit: 10, offset: 20) {
name
price
}
}
Cursor pagination uses values like first and after.
{
products(first: 10, after: “cursor123”) {
edges {
node {
name
price
}
cursor
}
}
}
Pagination improves performance, reduces response size, and avoids unnecessary database load.
14. What is cursor-based pagination?
Cursor-based pagination is a pagination method where the client uses a cursor to fetch the next or previous set of records. A cursor is usually an encoded value that points to a specific record position.
Example:
{
products(first: 10, after: “cursor_10”) {
edges {
node {
id
name
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}
Here:
- first: 10 asks for 10 records.
- after: “cursor_10” tells the server where to continue.
- endCursor is used for the next request.
- hasNextPage tells whether more records are available.
Cursor pagination is preferred for large or frequently changing datasets because it is more stable than offset pagination.
| Feature | Offset Pagination | Cursor Pagination |
| How it works | Uses page number or offset | Uses cursor position |
| Example | limit: 10, offset: 20 | first: 10, after: “cursor” |
| Best for | Small/simple datasets | Large or changing datasets |
| Performance | Can become slow for large offsets | Usually more efficient |
| Data consistency | May skip/duplicate items if data changes | More stable |
| User experience | Good for numbered pages | Good for infinite scroll/load more |
15. How do you version a GraphQL API?
GraphQL APIs are usually not versioned using URLs like REST APIs.
In REST, versioning often looks like this:
/api/v1/users
/api/v2/users
In GraphQL, versioning is commonly handled by evolving the schema carefully without breaking existing clients.
Common GraphQL versioning practices include:
- Add new fields instead of changing existing fields.
- Deprecate old fields using @deprecated.
- Avoid removing fields immediately.
- Avoid changing field return types directly.
- Create new fields when behaviour changes.
- Communicate schema changes to frontend teams.
- Track usage before removing deprecated fields.
Example:
type User {
fullName: String @deprecated(reason: “Use firstName and lastName instead”)
firstName: String
lastName: String
}
This allows old clients to continue working while new clients move to the updated fields.
In GraphQL, the preferred approach is schema evolution, not frequent URL-based versioning.
Conceptual/Scenario-based GraphQL Interview Questions
These conceptual GraphQL interview questions test how well you can apply GraphQL concepts in real application scenarios.
This section covers practical situations like over-fetching, slow queries, nested data, authorization, schema exposure, error handling, API security, and choosing between REST and GraphQL.
1. A frontend developer needs only a username and email, but the API returns full user details. How can GraphQL help?
GraphQL solves this by allowing the frontend developer to request only the required fields from the API. Instead of receiving the complete user object with address, phone number, profile image, orders, and other details, the client can ask only for name and email.
Example:
{
user(id: 1) {
name
}
}
The server will return only the requested fields:
This reduces unnecessary data transfer, improves frontend performance, and is especially useful for mobile apps or pages that need limited data.
2. A GraphQL query is becoming slow. What checks would you perform?
If a GraphQL query is slow, first check whether the query is requesting too much nested data or large lists without pagination. Then check resolver performance, database queries, and whether the N+1 problem is happening.
Important checks include:
- Is the query deeply nested?
- Are resolvers making repeated database calls?
- Is pagination missing for large lists?
- Are database indexes available for filtered fields?
- Is DataLoader used for batching?
- Are unnecessary fields being requested?
- Is caching used where suitable?
For example, if a query fetches users, posts, and comments together, each nested resolver may hit the database multiple times. Optimizing resolvers, adding pagination, and using DataLoader can improve performance.
3. A user should access only their own orders. How would you handle this in GraphQL?
This should be handled using authentication and authorization inside the GraphQL server. First, verify the user using a token such as JWT. After verification, store the logged-in user details in the GraphQL context.
Then, in the resolver, fetch only the orders that belong to that logged-in user.
Example:
orders: (parent, args, context) => {
if (!context.user) {
throw new Error(“Not authenticated”);
}
return getOrdersByUserId(context.user.id);
}
The client should not pass another user’s ID to access orders. The server should always use the authenticated user ID from context. This prevents users from accessing other users’ private data.
4. A GraphQL API exposes too much schema information. What would you check?
If a GraphQL API exposes too much schema information, I would first check whether introspection is enabled in production. Introspection allows clients to explore the schema, including available queries, mutations, types, and fields.
In development, introspection is useful. But in production, it may expose internal API structure to unwanted users.
I would check:
- Is introspection enabled publicly?
- Is GraphQL Playground or GraphiQL open in production?
- Are sensitive fields visible in the schema?
- Are proper authentication checks applied?
- Are admin-only fields protected?
- Are deprecated or internal fields still exposed?
The best approach is to restrict introspection, protect documentation tools, remove unnecessary fields, and enforce authorization at resolver level.
5. A nested query is hitting the database too many times. What could be the issue?
The issue is likely the N+1 problem. This happens when GraphQL first fetches a list of records and then separately runs another database query for each nested field.
For example:
{
users {
name
orders {
amount
}
}
}
The server may run 1 query to fetch all users and then one extra query for each user’s orders. If there are 100 users, this can become 101 database queries.
To fix this, use batching and caching with DataLoader. Instead of fetching orders one user at a time, DataLoader can fetch orders for all users in a single batch query.
6. A mobile app needs less data than a web app. How does GraphQL help?
GraphQL helps because different clients can request different sets of fields from the same API. A mobile app can ask for limited data to keep the response lightweight, while a web app can request more detailed data for a larger screen.
Mobile app query:
{
product(id: 1) {
name
price
}
}
Web app query:
{
product(id: 1) {
name
price
description
reviews {
rating
comment
}
}
}
Both clients use the same GraphQL endpoint, but the response changes based on the fields requested. This improves performance and avoids building separate APIs for mobile and web.
7. How would you design a GraphQL schema for a blog application?
For a blog application, I would design the schema around main entities such as User, Post, Comment, and Category.
Example:
type User {
id: ID!
name: String!
email: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment] }
type Comment {
id: ID!
text: String!
author: User!
}
Then I would define queries for reading data and mutations for creating or updating data.
type Query {
posts: [Post]
post(id: ID!): Post
}
type Mutation {
createPost(title: String!, content: String!): Post
}
This keeps the schema clear, relationship-based, and easy to extend.
8. How would you handle errors in a GraphQL response?
GraphQL errors are usually returned in the errors field of the response. The response may contain both data and errors if part of the query succeeds and another part fails.
Example:
{
“data”: {
“user”: null
},
“errors”: [
{
“message”: “User not found”,
“path”: [“user”]
}
]
}
In resolvers, errors can be handled by validating inputs, checking permissions, and throwing meaningful errors.
For production APIs, error messages should be clear but not expose sensitive internal details like database queries, stack traces, or server paths. Common error types include validation errors, authentication errors, authorization errors, and resource-not-found errors.
9. How would you secure a GraphQL endpoint?
To secure a GraphQL endpoint, I would protect both access and query execution. First, use authentication such as JWT or session-based login. Then apply authorization inside resolvers to ensure users can access only permitted data.
Important security steps include:
- Validate authentication tokens.
- Use resolver-level authorization.
- Restrict introspection in production if needed.
- Disable public GraphQL Playground in production.
- Apply query depth limits.
- Apply query complexity limits.
- Use rate limiting.
- Validate all input arguments.
- Avoid exposing internal error details.
- Use HTTPS.
- Protect sensitive fields.
GraphQL gives clients flexibility, so the server must strictly control permissions, query cost, and exposed schema details.
10. How would you decide between REST and GraphQL for a project?
I would choose based on the project’s data requirements, frontend needs, and API complexity.
GraphQL is a good choice when the application has complex or related data, different clients need different responses, or the frontend wants control over selected fields. It is useful for dashboards, mobile apps, and apps that need data from multiple sources.
REST is better when the API is simple, resource-based, cache-friendly, and does not require highly flexible data fetching.
Example:
For a simple contact form API, REST is enough.
For an e-commerce app showing products, reviews, sellers, offers, and recommendations in one screen, GraphQL can be more efficient.
So, REST is simple and predictable, while GraphQL is better for flexible and complex data needs.
Best Ways to Prepare for GraphQL Interviews
Preparing for GraphQL interviews becomes easier when you understand both API fundamentals and practical implementation.
Since most GraphQL interview questions test how well you can design schemas, write queries, handle resolvers, and solve real API problems, focus on concepts, practice, and project-based learning together.
- Learn GraphQL API Basics First: Start with HTTP, REST APIs, JSON, request-response flow, status codes, and endpoints.
- Understand GraphQL Core Concepts: Revise important topics like schema, types, queries, mutations, resolvers, arguments, variables, fragments, subscriptions, and error handling.
- Practise GraphQL Queries and Build Small Projects: Write queries for nested data, filtered data, aliases, fragments, and variables using tools like GraphQL Playground or Apollo Studio. Then build simple projects like a blog API, user profile API, product catalogue API, or task management API to understand real implementation.
- Practise MCQs and Scenario-based Interview Questions: Solve GraphQL MCQs, API-based questions, debugging questions, and scenario-based problems regularly.
- Use PlacementPreparation.io for Practice: Use PlacementPreparation.io to practise GraphQL MCQs, technical questions, mock tests, and interview-based exercises. It is useful for freshers preparing for placement rounds, technical interviews, and API development roles.
- Learn with GUVI Courses and GUVI Zen Class: Use GUVI courses to learn web development, backend development, APIs, JavaScript, Node.js, and full-stack concepts in a structured way. You can also choose GUVI Zen Class for mentor-led learning, hands-on projects, coding practice, and career guidance.
Final Words
GraphQL is an important API technology for freshers preparing for frontend, backend, full-stack, API developer, and web development roles. It helps developers build flexible APIs where clients can request only the data they need, making applications faster and easier to manage.
To prepare well, practise GraphQL queries, schema design, resolvers, variables, fragments, MCQs, mock tests, and scenario-based interview questions regularly. The more you practise real examples and common GraphQL interview questions and answers, the easier it becomes to explain concepts clearly in interviews.
FAQs
Yes, GraphQL continues to be widely adopted by organizations building modern web and mobile applications. Its ability to provide flexible data fetching and improve API efficiency makes it a valuable skill for developers and API engineers.
Many leading technology companies use GraphQL, including Meta, Shopify, GitHub, Airbnb, Pinterest, and Netflix. These organizations leverage GraphQL to simplify data access across complex applications.
GraphQL introduces concepts such as schemas, resolvers, and query languages, which may require some initial learning. However, developers often find it easier to work with once they understand its structure because it provides greater control over data retrieval.
Not always. While GraphQL can reduce the need for multiple REST endpoints, many organizations use both technologies together. The choice depends on application requirements, performance considerations, and existing architecture.
Some common challenges include increased server-side complexity, caching difficulties, query optimization concerns, and the need for proper security measures to prevent expensive queries from affecting performance.
Yes, GraphQL is frequently discussed in backend, full-stack, and API development interviews. Understanding GraphQL concepts, use cases, and implementation patterns can help candidates stand out in modern software engineering roles.
Related Posts


Top Selenium Interview Questions for Freshers
Selenium remains one of the most important tools for freshers preparing for QA, automation testing, software testing, SDET, web testing, …
Warning: Undefined variable $post_id in /var/www/wordpress/wp-content/themes/placementpreparation/template-parts/popup-zenlite.php on line 1050








