
- GraphQL - Home
- GraphQL - Introduction
- GraphQL - Environment Setup
- GraphQL - Architecture
- GraphQL - Application Components
- GraphQL - Example
- GraphQL - Type System
- GraphQL - Schema
- GraphQL - Resolver
- GraphQL - Query
- GraphQL - Mutation
- GraphQL - Validation
- GraphQL - JQuery Integration
- GraphQL - React Integration
- GraphQL - Apollo Client
- GraphQL - Authenticating Client
- GraphQL - Caching
GraphQL Cheatsheet
This GraphQL cheatsheet provides a concise reference to key GraphQL concepts, including queries, mutations, schemas, resolvers, and advanced topics like subscriptions, authentication, and performance optimization. It is designed to help developers quickly understand and apply GraphQL's flexible querying capabilities and efficient data fetching mechanisms. Use this guide as a fast resource for building robust and scalable APIs with GraphQL.
Table of Contents
- Overview
- Core Concepts
- Basic GraphQL Query Syntax
- Mutations
- GraphQL Schema
- Resolvers
- GraphQL Clients
- Apollo Client Setup
- Advanced GraphQL
- GraphQL over HTTP
- Subscriptions
- Authentication & Authorization
- Error Handling
- Filtering, Pagination & Sorting
- GraphQL Directives
- Performance Optimization
Overview
GraphQL is a query language for APIs that enables clients to request only the data they need. It provides a flexible and efficient alternative to REST APIs by allowing nested queries and reducing the need for multiple endpoints. Tools like GraphiQL help developers execute queries and explore the API schema.
Key Features:
- Clients fetch only the required fields.
- Supports nested queries for complex relations.
- Reduces the need for multiple endpoints.
- Tools like GraphiQL help execute queries and provide documentation.
Core Concepts
Fundamental elements of GraphQL that define how data is structured, queried, and modified.
- Query: Fetch data.
- Mutation: Modify data.
- Schema: Defines data structure between client and server.
- Resolvers: Handle data fetching logic.
Basic GraphQL Query Syntax
Queries structure and format used to retrieve data in GraphQL.
Simple Query: Fetches specific user details using a straightforward query format.
query { user(id: "1") { id name age } }
Query with Relations: Retrieves user details along with related company information in a single request.
query { user(id: "1") { id name company { id name } } }
Parameterized Queries: Uses variables to fetch dynamic data based on input parameters.
query UserQuery($id: ID!) { user(id: $id) { id name } }
Variables: Defines values for parameters in queries to improve reusability.
{ "id": "1" }
Mutations
Mutations are GraphQL operations that enable data creation, modification, and deletion.
Example:
mutation { addUser(name: "Alice", age: 25) { id name } }
Parameterized Mutation: Uses variables to dynamically update user details.
mutation UpdateUser($id: ID!, $name: String) { updateUser(id: $id, name: $name) { id name } }
Variables: Provides structured input values for mutation execution.
{ "id": "1", "name": "Bob" }
GraphQL Schema
Schema defines the structure, types, and relationships within a GraphQL API.
Basic Example:
type Query { user(id: ID!): User company(id: ID!): Company } type Mutation { addUser(name: String!, age: Int!): User } type User { id: ID! name: String age: Int company: Company } type Company { id: ID! name: String users: [User] }
Built-in Scalar Types:
Includes Int, Float, String, Boolean, and ID for structured data representation.
- Int: A signed 32bit integer.
- Float: A signed double-precision floating-point value.
- String: A UTF8 character sequence.
- Boolean: true or false.
- ID: A unique identifier.
Type Modifiers:
Defines nullable, non-nullable, and list types to enforce data integrity.
- String: Nullable.
- String!: Non-nullable.
- [String]: List of strings.
- [String]!: Required list.
- [String!]!: Required list of required strings.
Resolvers
Resolvers are the functions that handle GraphQL queries and return appropriate responses from the data source.
Resolvers define how fields fetch data: An example of a resolver function that retrieves and modifies user data based on client requests.
const resolvers = { Query: { user(parent, args) { return users.find(user => user.id === args.id); }, }, Mutation: { addUser(parent, args) { const newUser = { id: generateId(), ...args }; users.push(newUser); return newUser; }, }, };
GraphQL Client
Libraries that simplify the process of interacting with GraphQL APIs from the client side.
-
Lokka: Lightweight, basic features.
-
Apollo Client: Feature-rich and developer-friendly.
- Relay: High-performance, but complex.
Apollo Client Setup
Setting up Apollo Client for seamless GraphQL API interaction.
Initialization: Configures Apollo Client by specifying the GraphQL API endpoint.
import ApolloClient from 'apollo-client'; const client = new ApolloClient({ uri: '/graphql', });
Query Example: Demonstrates how to fetch data from a GraphQL API using Apollo Client.
import gql from 'graphql-tag'; const query = gql` query { user(id: "1") { id name } } `;
Mutation Example: This shows how to modify data using a GraphQL mutation in Apollo.
const mutation = gql` mutation AddUser($name: String!, $age: Int!) { addUser(name: $name, age: $age) { id name } } `;
Advanced GraphQL
Enhancing GraphQL capabilities with additional features like fragments, aliases, and interfaces.
Fragments: Reusable query components that avoid redundancy and improve efficiency.
fragment userFields on User { id name age } query { user(id: "1") { ...userFields } }
Aliases: Assigns custom names to query responses to differentiate between similar data structures.
{ alice: user(id: "1") { name } bob: user(id: "2") { name } }
Interfaces: Defines shared fields across multiple types for better code reuse and type safety.
interface Entity { id: ID! } type User implements Entity { id: ID! name: String }
GraphQL over HTTP
How GraphQL queries and mutations are executed over HTTP requests.
GET: Sends queries via URL parameters for simple data retrieval.
fetch('/graphql?query={ user { id name } }');
POST: Sends queries and mutations in the request body for more complex operations.
fetch('/graphql', { method: 'POST', body: JSON.stringify({ query: `query { user(id: "1") { id name } }`, }), });
Subscriptions
Enables real-time updates using GraphQL by listening to specific data changes.
Type | Description | Code Example |
Basic Subscription | Defines a simple subscription to listen for an event. |
subscription { event { field } } |
Subscription with Variables | Uses input variables for dynamic event filtering. |
subscription ($input: InputType) { event(input: $input) { field } } |
Input Type | Defines the structure of the input variable used in the subscription. |
input InputType { field: String } |
Trigger Event | The server triggers an event (e.g., like/unlike) using PubSub or WebSockets. |
// Handled in backend logic |
Example Subscription | Listens for new likes on a story. |
subscription StoryLike($input: Input) { storyLike(input: $input) { likers { count } } } |
Authentication & Authorization
Ensuring secure access control in GraphQL APIs using tokens and role-based restrictions.
Authentication Setup
Extract the Token from Headers: Extracts and verifies user authentication tokens from request headers.
context: async ({ req }) => { const token = req.headers.authorization || ''; const user = await getUser(token); // Fetch user info using token return { user }; };
Deny Unauthenticated Users: Prevents access to GraphQL operations without valid authentication.
if (!user) { throw new GraphQLError('User is not authenticated', { extensions: { code: 'UNAUTHENTICATED', http: { status: 401 } }, }); }
Authorization Techniques
Resolver-based Authorization: Implements role-based access control at the resolver level.
users: (parent, args, contextValue) => { if (!contextValue.user || !contextValue.user.roles.includes('admin')) return null; return contextValue.models.User.getAll(); };
API-wide Authorization: API access globally based on authentication status.
context: async ({ req }) => { const user = getUser(req.headers.authorization); if (!user) throw new GraphQLError('Unauthenticated'); return { user }; };
Using Models for Access Control: Validates permissions before allowing data retrieval.
export const generateUserModel = ({ user }) => ({ getAll: () => { if (!user || !user.roles.includes('admin')) return null; return fetch('http://example.com/users'); }, });
Custom Directive Authorization
Define a Schema Directive: Uses schema directives to enforce authorization rules.
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION enum Role { ADMIN REVIEWER USER } type User @auth(requires: USER) { name: String banned: Boolean @auth(requires: ADMIN) canPost: Boolean @auth(requires: REVIEWER) }
Error Handling
Handling, formatting, and reporting errors in GraphQL APIs.
Aspect | Description | Example/Error Code |
Error Response | Errors are listed in the errors array. | GRAPHQL_PARSE_FAILED |
Built-in Error Codes | Predefined common error codes. | INTERNAL_SERVER_ERROR |
Custom Errors | Define errors with GraphQLError. | FORBIDDEN, UNAUTHENTICATED |
FormatError Hook | Customize error messages. | Change GRAPHQL_VALIDATION_FAILED. |
Masking Errors | Hide sensitive error details. | Mask API keys or stacktraces. |
Error Reporting | Filter/report errors to Apollo Studio. | Ignore minor errors. |
HTTP Status Codes | Modify HTTP status in responses. | Set 404 for specific cases. |
Logging Errors | Log errors; hide stacktrace in production. | Disable stacktrace in production. |
Usage Reporting | Adjust error details before reporting. | Remove PII from errors. |
Filtering, Pagination & Sorting
Efficient data retrieval techniques using filters, pagination, and sorting.
Feature | Description | Query Code |
Filtering | Filter Link items by description or URL. | feed(filter: String): [Link!]! |
Pagination | Use skip (start index) and take (limit) for pagination. | feed(filter: String, skip: Int, take: Int): [Link!]! |
Sorting | Sort links by description, URL, or createdAt in ascending (asc) or descending (desc) order. |
input LinkOrderByInput { description: Sort url: Sort createdAt: Sort } enum Sort { asc desc } feed(orderBy: LinkOrderByInput): [Link!]! |
Count Links | Return the total count of Link items along with filtered/sorted links. |
type Feed { links: [Link!]! count: Int! } feed: Feed! |
Directives
Special annotations that modify GraphQL query behavior dynamically.
Directive | Explanation | Example |
@deprecated | Marks a field or enum value as outdated with an optional reason. | field: String @deprecated(reason: "Use `newField`.") |
@skip | Excludes a field/fragment if the condition is true. | query { field @skip(if: true) } |
@include | Includes a field/fragment only if the condition is true. | query { field @include(if: true) } |
Custom Directive | Adds custom logic to schema or operations. | directive @uppercase on FIELD_DEFINITION type Query { field: String @uppercase } |
Directive Locations | Specifies valid placements (e.g., fields, arguments, enums). | directive @example on FIELD_DEFINITION |
Performance Optimization
Techniques to improve GraphQL API performance and reduce redundant queries.
Technique | Description | Code Example |
Cache Redirection | Resolve data from the cache using custom resolvers. | cacheRedirects: { Query: { book: (_, args) => toIdValue({ __typename: 'Book', id: args.id }) } } |
Prefetching Data | Load data into the cache before it's needed. | client.query({ query: GET_DOG, variables: { breed: data.breed } }); |
Query Splitting | Split large queries into cached and server queries. | QUERY 1: { id title } QUERY 2: { id episodes { id title } } |
Custom Resolvers | Map queries to cached data. | cacheResolvers: { Query: { oneSeries: (_, { id }) => toIdValue({ __typename: 'Series', id }) } } |
Fragments | Reuse query parts to avoid over-fetching. | fragment EpisodeDetails on Episode { id title cover } |