🚀 GraphQL

A Query Language for Your API

👋 Welcome to GraphQL!

GraphQL is a modern alternative to REST APIs. It gives clients the power to ask for exactly what they need, making APIs more flexible and efficient.

Learn how to build powerful, flexible APIs with GraphQL!

🤔 What is GraphQL?

GraphQL is a query language for APIs and a runtime for executing those queries. Developed by Facebook in 2012 and open-sourced in 2015, it provides a complete and understandable description of the data in your API.

Key Concept:

With REST, you might need multiple endpoints:

GET /users/1 GET /users/1/posts GET /users/1/friends

With GraphQL, you make ONE request:

query { user(id: 1) { name posts { title } friends { name } } }

⚖️ GraphQL vs REST

Feature REST GraphQL
Endpoints Multiple endpoints Single endpoint
Data Fetching Fixed data structure Client specifies exactly what it needs
Over-fetching Common problem Eliminated
Under-fetching Requires multiple requests Single request gets all data
Versioning Often needs /v1, /v2 No versioning needed
Documentation Manual (Swagger, etc.) Self-documenting

🎯 Core Concepts

📋

Schema

Defines the structure of your API

Types, queries, mutations

🔍

Queries

Read data from the server

Like GET in REST

✏️

Mutations

Modify data on the server

Like POST, PUT, DELETE in REST

🔔

Subscriptions

Real-time updates

WebSocket-based

📝 GraphQL Schema

Defining Types

# User type definition type User { id: ID! # ! means required name: String! email: String! age: Int posts: [Post!]! # Array of posts friends: [User!]! } # Post type definition type Post { id: ID! title: String! content: String! author: User! comments: [Comment!]! createdAt: String! } # Comment type definition type Comment { id: ID! text: String! author: User! post: Post! } # Query type - defines what can be queried type Query { user(id: ID!): User users: [User!]! post(id: ID!): Post posts: [Post!]! } # Mutation type - defines what can be modified type Mutation { createUser(name: String!, email: String!): User! updateUser(id: ID!, name: String, email: String): User! deleteUser(id: ID!): Boolean! createPost(title: String!, content: String!, authorId: ID!): Post! } # Subscription type - real-time updates type Subscription { postAdded: Post! commentAdded(postId: ID!): Comment! }

🔍 Writing Queries

Basic Query

# Get a single user query { user(id: "1") { name email } } # Response { "data": { "user": { "name": "John Doe", "email": "john@example.com" } } }

Nested Query

# Get user with their posts query { user(id: "1") { name email posts { title content comments { text author { name } } } } }

Query with Variables

# Query definition query GetUser($userId: ID!) { user(id: $userId) { name email posts { title } } } # Variables (sent separately) { "userId": "1" }

Multiple Queries

query { user1: user(id: "1") { name } user2: user(id: "2") { name } allPosts: posts { title } }

✏️ Mutations

Create Data

mutation { createUser(name: "Alice", email: "alice@example.com") { id name email } } # Response { "data": { "createUser": { "id": "3", "name": "Alice", "email": "alice@example.com" } } }

Update Data

mutation { updateUser(id: "1", name: "John Updated") { id name email } }

Delete Data

mutation { deleteUser(id: "1") } # Response { "data": { "deleteUser": true } }

🔧 Building a GraphQL Server (Node.js)

Setup with Apollo Server

// Install dependencies // npm install apollo-server graphql const { ApolloServer, gql } = require('apollo-server'); // Define schema const typeDefs = gql` type User { id: ID! name: String! email: String! posts: [Post!]! } type Post { id: ID! title: String! content: String! author: User! } type Query { users: [User!]! user(id: ID!): User posts: [Post!]! post(id: ID!): Post } type Mutation { createUser(name: String!, email: String!): User! createPost(title: String!, content: String!, authorId: ID!): Post! } `; // Sample data let users = [ { id: '1', name: 'John Doe', email: 'john@example.com' }, { id: '2', name: 'Jane Smith', email: 'jane@example.com' } ]; let posts = [ { id: '1', title: 'First Post', content: 'Hello World', authorId: '1' }, { id: '2', title: 'Second Post', content: 'GraphQL is awesome', authorId: '1' } ]; // Define resolvers const resolvers = { Query: { users: () => users, user: (parent, args) => users.find(user => user.id === args.id), posts: () => posts, post: (parent, args) => posts.find(post => post.id === args.id) }, Mutation: { createUser: (parent, args) => { const newUser = { id: String(users.length + 1), name: args.name, email: args.email }; users.push(newUser); return newUser; }, createPost: (parent, args) => { const newPost = { id: String(posts.length + 1), title: args.title, content: args.content, authorId: args.authorId }; posts.push(newPost); return newPost; } }, User: { posts: (parent) => posts.filter(post => post.authorId === parent.id) }, Post: { author: (parent) => users.find(user => user.id === parent.authorId) } }; // Create server const server = new ApolloServer({ typeDefs, resolvers }); // Start server server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });

💻 Using GraphQL in Frontend

Using Fetch API

async function fetchGraphQL(query, variables = {}) { const response = await fetch('http://localhost:4000/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables }) }); const { data, errors } = await response.json(); if (errors) { console.error('GraphQL Errors:', errors); throw new Error(errors[0].message); } return data; } // Usage - Query const GET_USER = ` query GetUser($id: ID!) { user(id: $id) { name email posts { title } } } `; const userData = await fetchGraphQL(GET_USER, { id: '1' }); console.log(userData.user); // Usage - Mutation const CREATE_USER = ` mutation CreateUser($name: String!, $email: String!) { createUser(name: $name, email: $email) { id name email } } `; const newUser = await fetchGraphQL(CREATE_USER, { name: 'Alice', email: 'alice@example.com' }); console.log(newUser.createUser);

Using Apollo Client (React)

// Install: npm install @apollo/client graphql import { ApolloClient, InMemoryCache, ApolloProvider, useQuery, useMutation, gql } from '@apollo/client'; // Setup Apollo Client const client = new ApolloClient({ uri: 'http://localhost:4000/graphql', cache: new InMemoryCache() }); // Wrap app with ApolloProvider function App() { return ( ); } // Define query const GET_USERS = gql` query GetUsers { users { id name email } } `; // Use query in component function UserList() { const { loading, error, data } = useQuery(GET_USERS); if (loading) return

Loading...

; if (error) return

Error: {error.message}

; return ( ); } // Define mutation const CREATE_USER = gql` mutation CreateUser($name: String!, $email: String!) { createUser(name: $name, email: $email) { id name email } } `; // Use mutation in component function CreateUserForm() { const [createUser, { loading, error }] = useMutation(CREATE_USER, { refetchQueries: [{ query: GET_USERS }] }); const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(e.target); createUser({ variables: { name: formData.get('name'), email: formData.get('email') } }); }; return (
{error &&

Error: {error.message}

}
); }

🔔 Subscriptions (Real-time)

// Server setup with subscriptions const { ApolloServer, gql, PubSub } = require('apollo-server'); const pubsub = new PubSub(); const typeDefs = gql` type Post { id: ID! title: String! content: String! } type Query { posts: [Post!]! } type Mutation { createPost(title: String!, content: String!): Post! } type Subscription { postAdded: Post! } `; const resolvers = { Mutation: { createPost: (parent, args) => { const newPost = { id: String(posts.length + 1), title: args.title, content: args.content }; posts.push(newPost); // Publish event pubsub.publish('POST_ADDED', { postAdded: newPost }); return newPost; } }, Subscription: { postAdded: { subscribe: () => pubsub.asyncIterator(['POST_ADDED']) } } }; // Client usage (React) const POST_ADDED = gql` subscription OnPostAdded { postAdded { id title content } } `; function PostFeed() { const { data, loading } = useSubscription(POST_ADDED); if (loading) return

Waiting for posts...

; return (

New Post!

{data.postAdded.title}

); }

💡 GraphQL Best Practices

Best Practices:

Pagination Example

type Query { posts(first: Int, after: String): PostConnection! } type PostConnection { edges: [PostEdge!]! pageInfo: PageInfo! } type PostEdge { node: Post! cursor: String! } type PageInfo { hasNextPage: Boolean! endCursor: String }

🛠️ GraphQL Tools

GraphQL Playground

Interactive IDE for GraphQL

  • Test queries
  • Auto-complete
  • Documentation explorer

Apollo Studio

Complete GraphQL platform

  • Schema management
  • Performance monitoring
  • Team collaboration

GraphiQL

In-browser IDE

  • Query editor
  • Schema explorer
  • History

Hasura

Instant GraphQL APIs

  • Auto-generate from database
  • Real-time subscriptions
  • Authorization

🎓 Our Training Course

Learn GraphQL

Take our comprehensive GraphQL course:

📚 GraphQL Course →

🚀 Master GraphQL!

Build modern, flexible APIs with GraphQL

Start Learning →

📖 Related Topics