GraphQL - Interview preparation guide
Thilan Dissanayaka Interview Guides Mar 22, 2020

GraphQL - Interview preparation guide

What is GraphQL?

GraphQL is a query language for APIs and a runtime for executing those queries. It allows clients to request exactly the data they need, reducing over-fetching and under-fetching issues. It was developed by Facebook in 2012 and open-sourced in 2015.

What are the core components of GraphQL?

  1. Schema: Defines the structure and types of data available.
  2. Query: Used to fetch data (equivalent to GET in REST).
  3. Mutation: Used to modify data (Create, Update, Delete).
  4. Subscription: Provides real-time updates.
  5. Resolver: Functions that fetch the actual data for the queries and mutations.

How is GraphQL different from REST?

Feature GraphQL REST
Data Fetching Request specific fields Fetch entire resources
Over-fetching No (only requested fields) Yes (fixed endpoint data)
Under-fetching No (nested queries allowed) Yes (multiple requests)
Versioning Not required Requires new endpoints
Performance Single request for complex data Multiple round-trips

What is a GraphQL schema?

A GraphQL schema is a blueprint that defines the types of data and operations (queries, mutations, subscriptions) supported by the API. Example schema:

type User {  
 id: ID!   name: String!   email: String! 
}  

type Query {   
getUser(id: ID!): User 
}  

type Mutation { 
createUser(name: String!, email: String!): User 
}

what is a GraphQL query?

A query is used to fetch data from the server.

Example query:

query {   getUser(id: \"1\") {     name     email   } }

What is a GraphQL mutation?

A mutation is used to modify data on the server (create, update, delete).

Example mutation:

mutation {   createUser(name: \"Alice\", email: \"[email protected]\") {     id     name   } }

What is a GraphQL subscription?

A subscription allows clients to receive real-time updates.

Example subscription:

subscription {   userAdded {     id     name   } }

What is a resolver in GraphQL?

Resolvers are functions that handle the logic behind GraphQL queries, mutations, and subscriptions.

Example resolver:

const resolvers = {   Query: {     getUser: (_, { id }) => getUserById(id),   },   Mutation: {     createUser: (_, { name, email }) => createUser(name, email),   }, };

What are GraphQL variables and why are they useful?

Variables make queries dynamic and reusable.

Example query with variables:

query GetUser($id: ID!) {   getUser(id: $id) {     name     email   } }

Passing variables:

{   \"id\": \"1\" }

What is a GraphQL fragment?

A fragment allows you to reuse fields in multiple queries.

Example fragment:

fragment UserFields on User {   id   name   email }  query {   getUser(id: \"1\") {     ...UserFields   } }

How does GraphQL handle errors?

GraphQL returns errors alongside a data field.

Example error response:

{   \"data\": null,   \"errors\": [     {       \"message\": \"User not found\",       \"locations\": [{ \"line\": 2, \"column\": 3 }],       \"path\": [\"getUser\"]     }   ] }

What are the benefits of using GraphQL?

  • Efficient Data Fetching: Clients request exactly the fields they need.
  • Strongly Typed Schema: Enforces a contract between client and server.
  • Single Endpoint: Access all resources through a single endpoint.
  • Reduced Over-fetching/Under-fetching: Flexible queries prevent these issues.
  • Real-time Updates: Via subscriptions for event-driven data.

What are the drawbacks of GraphQL?

  • Complexity: More setup and learning curve than REST.
  • Caching Challenges: Difficult to cache responses compared to REST.
  • Performance Overhead: Parsing and resolving dynamic queries may be slower.
  • Security Risks: Requires limiting query depth to avoid denial-of-service attacks.

What is introspection in GraphQL?

Introspection allows clients to query the schema itself and retrieve metadata.

Example introspection query:

`{   __schema {     types {       name       fields {         name       }     }   } }`

What are some best practices for designing GraphQL APIs?

  1. Schema Design: Keep the schema simple and modular.
  2. Pagination: Implement cursor-based pagination for large datasets.
  3. Security: Limit query depth and rate-limit requests.
  4. Batching: Use DataLoader for optimizing N+1 query problems.
  5. Error Handling: Provide clear and consistent error responses.
  6. Caching: Use persisted queries or cache at the resolver level.

How do you implement authentication and authorization in GraphQL?

  • Authentication: Use tokens (e.g., JWT) to verify users.
  • Authorization: Check user roles in resolvers before returning data.

Example context for authorization:

const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const token = req.headers.authorization || \"\"; const user = verifyToken(token); return { user }; }, });

What are Apollo Client and Apollo Server?

  • Apollo Client: A state management library for consuming GraphQL APIs.
  • Apollo Server: A GraphQL server implementation supporting queries, mutations, and subscriptions.

How do you handle pagination in GraphQL?

Implement cursor-based pagination using startCursor, endCursor, and hasNextPage.

Example schema:

type UserConnection { edges: [UserEdge] pageInfo: PageInfo } type UserEdge { cursor: String node: User } type PageInfo { hasNextPage: Boolean endCursor: String }

What are some common GraphQL tools and libraries?

  1. Apollo Server/Client: Comprehensive GraphQL solution.
  2. GraphQL.js: Core reference implementation.
  3. GraphQL Code Generator: Generates TypeScript types from schema.
  4. Hasura: Auto-generates GraphQL over databases.

What is schema stitching and federation?

  • Schema Stitching: Combines multiple GraphQL schemas into a single schema.
  • Federation: Distributes a GraphQL schema across multiple services while presenting a unified API.
ALSO READ
Remote Code Execution (RCE)
Jan 02 Application Security

Remote Code Execution (RCE) is the holy grail of application security vulnerabilities. It allows an attacker to execute arbitrary code on a remote server — and the consequences are as bad as it sounds. In this post, we'll go deep into RCE across multiple languages, including PHP, Java, Python, and Node.js.

SQL Injection Login Bypass
Feb 10 Application Security

SQL Injection (SQLi) is one of the oldest and most fundamental web application vulnerabilities. While modern frameworks have made it harder to introduce, understanding SQL injection is essential for anyone learning web security. In this post, we'll break it down from the ground up using a classic login bypass.

Bypassing DEP with Return-to-libc
Apr 05 Exploit development

DEP makes the stack non-executable — our shellcode can't run. The simplest bypass? Don't inject code at all. Instead, call functions that already exist in libc. In this post, we exploit a stack overflow to call system('/bin/sh') without writing a single byte of shellcode.

Singleton Pattern explained simply
Jan 27 Software Architecture

Ever needed just one instance of a class in your application? Maybe a logger, a database connection, or a configuration manager? This is where the Singleton Pattern comes in — one of the simplest but...

Exploiting a format string vulnerebility on Linux
Apr 12 Exploit development

A misused printf can leak stack contents, read arbitrary memory, and write to arbitrary addresses. Format string vulnerabilities are one of the most powerful bug classes in C and they're the key to defeating ASLR. In this post, we exploit printf from leak to shell.

Access Control Models
Apr 08 Identity & Access Management

Access control is one of the most fundamental concepts in security. Every time you set file permissions, assign user roles, or restrict access to a resource, you're implementing some form of access control. But not all access control is created equal...