logo
eng-flag

GraphQL Cheatsheet

Table of Contents

  1. Introduction to GraphQL
  2. Schema Definition Language (SDL)
  3. Types
  4. Queries
  5. Mutations
  6. Subscriptions
  7. Resolvers
  8. Variables
  9. Directives
  10. Fragments
  11. Introspection
  12. Authentication and Authorization
  13. Best Practices
  14. Tools

Introduction to GraphQL

GraphQL is a query language for APIs and a runtime for executing those queries with your existing data. It provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need, makes it easier to evolve APIs over time, and enables powerful developer tools.

Schema Definition Language (SDL)

GraphQL uses SDL to define the structure of your data.

type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
}

type Query {
  user(id: ID!): User
  users: [User!]!
  post(id: ID!): Post
  posts: [Post!]!
}

type Mutation {
  createUser(name: String!, email: String!): User!
  createPost(title: String!, content: String!, authorId: ID!): Post!
}

Types

Basic Scalar Types:

Int: 32-bit integer
Float: Double-precision floating-point value
String: UTF-8 character sequence
Boolean: true or false
ID: Unique identifier

Object Types:

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

Input Types:

input UserInput {
  name: String!
  email: String!
}

Enum Types:

enum Role {
  USER
  ADMIN
  MODERATOR
}

Interface Types:

interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  name: String!
}

Union Types:

union SearchResult = User | Post | Comment

Queries

Basic Query:

query {
  user(id: "123") {
    name
    email
    posts {
      title
    }
  }
}

Multiple Queries:

query {
  user(id: "123") {
    name
  }
  posts {
    title
  }
}

Aliases:

query {
  user1: user(id: "123") {
    name
  }
  user2: user(id: "456") {
    name
  }
}

Mutations

Basic Mutation:

mutation {
  createUser(name: "John Doe", email: "john@example.com") {
    id
    name
    email
  }
}

Multiple Mutations:

mutation {
  createUser(name: "John Doe", email: "john@example.com") {
    id
  }
  createPost(title: "Hello World", content: "This is my first post", authorId: "123") {
    id
    title
  }
}

Subscriptions

Basic Subscription:

subscription {
  newPost {
    id
    title
    author {
      name
    }
  }
}

Resolvers

Example resolver in JavaScript:

const resolvers = {
  Query: {
    user: (parent, args, context, info) => {
      return getUserById(args.id);
    },
    posts: () => getAllPosts(),
  },
  Mutation: {
    createUser: (parent, args, context, info) => {
      return createNewUser(args.name, args.email);
    },
  },
  User: {
    posts: (parent) => getPostsByUserId(parent.id),
  },
};

Variables

Query with Variables:

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

Variable Values:

{
  "userId": "123"
}

Directives

Built-in Directives:

query GetUser($includeEmail: Boolean!) {
  user(id: "123") {
    name
    email @include(if: $includeEmail)
  }
}

Custom Directive:

directive @deprecated(reason: String) on FIELD_DEFINITION

type User {
  id: ID!
  name: String!
  oldField: String @deprecated(reason: "Use newField instead")
  newField: String
}

Fragments

Fragment Definition and Usage:

fragment UserFields on User {
  id
  name
  email
}

query {
  user(id: "123") {
    ...UserFields
    posts {
      title
    }
  }
}

Introspection

Introspection Query:

query {
  __schema {
    types {
      name
      kind
      description
    }
  }
}

Authentication and Authorization

Context-based Authentication:

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

Resolver-level Authorization:

const resolvers = {
  Query: {
    sensitiveData: (parent, args, context) => {
      if (!context.user) throw new Error('You must be logged in');
      if (!context.user.hasPermission('READ_SENSITIVE_DATA')) {
        throw new Error('Not authorized');
      }
      return getSensitiveData();
    },
  },
};

Best Practices

  1. Design your schema with the client in mind
  2. Use meaningful and descriptive names
  3. Implement pagination for large collections
  4. Utilize DataLoader for batching and caching
  5. Handle errors gracefully
  6. Use input types for complex mutations
  7. Implement proper authentication and authorization
  8. Optimize resolvers for performance
  9. Use aliases to request the same field with different arguments
  10. Leverage fragments for reusable field selections
  11. Implement subscriptions for real-time updates
  12. Use schema stitching or federation for large-scale applications
  13. Document your schema using descriptions
  14. Utilize custom scalars for specific data types (e.g., DateTime)
  15. Implement field-level permissions when necessary

Tools

  1. GraphQL Playground - Interactive IDE
  2. Apollo Server - GraphQL server implementation
  3. GraphQL Voyager - Interactive graph visualization
  4. GraphQL Code Generator - Code generation based on GraphQL schema
  5. GraphQL Faker - Mock your GraphQL API with realistic data
  6. GraphQL Shield - Authorization middleware
  7. DataLoader - Batching and caching library
  8. Apollo Client - Comprehensive GraphQL client
  9. Prisma - Database toolkit and ORM
  10. GraphQL Nexus - Code-first GraphQL schema construction

2024 © All rights reserved - buraxta.com