Isaac.

Introduction to GraphQL

Learn GraphQL: query exactly the data you need, nothing more.

By EMEPublished: February 20, 2025
graphqlapiquery languagerest alternativedata fetching

A Simple Analogy

GraphQL is like ordering at a restaurant. With REST (menu), you order the entire plate. With GraphQL, you specify exactly which ingredients you want—salad, no croutons, extra dressing on the side. You get precisely what you asked for.


What Is GraphQL?

GraphQL is a query language for APIs. Unlike REST where endpoints return fixed data, GraphQL lets clients specify exactly what data they need, reducing over-fetching and under-fetching.


Why Use GraphQL?

  • Efficient: Fetch only required fields
  • Strong typing: Schema defines all possible queries
  • Single endpoint: No multiple REST endpoints
  • Introspection: Self-documenting API
  • Real-time: Built-in subscription support
  • Flexible: Client controls response shape

REST vs. GraphQL

| Aspect | REST | GraphQL | |--------|------|---------| | Endpoints | Multiple (/users, /users/:id/posts) | Single endpoint | | Data shape | Fixed per endpoint | Client-specified | | Over-fetching | Common | Eliminated | | Under-fetching | Common | Eliminated | | Caching | Standard HTTP | More complex |


GraphQL Schema Example

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

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

type Query {
  user(id: ID!): User
  posts(limit: Int = 10): [Post!]!
}

Queries

# Simple query
query {
  user(id: "123") {
    name
    email
  }
}

# Nested query (fetch related data)
query {
  user(id: "123") {
    name
    posts {
      title
      createdAt
    }
  }
}

# With variables
query GetUserPosts($userId: ID!) {
  user(id: $userId) {
    name
    posts(limit: 5) {
      title
      content
    }
  }
}

.NET Implementation

using HotChocolate;
using HotChocolate.Execution.Configuration;

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Post> Posts { get; set; }
}

public class Query
{
    public User GetUser(int id, IUserRepository userRepo)
    {
        return userRepo.GetById(id);
    }
}

// Setup
var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddSubscriptionType<Subscription>();

var app = builder.Build();
app.MapGraphQL();
app.Run();

Real-World Benefits

Reduce bandwidth: Only request name and email instead of entire user object

# Instead of: /api/users/123 (returns 50+ fields)
query {
  user(id: 123) {
    name
    email
  }
}

Single query for complex data:

# Instead of: /api/users/123 + /api/users/123/posts + /api/posts/:id/comments
query {
  user(id: "123") {
    posts {
      comments {
        author { name }
      }
    }
  }
}

Related Concepts to Explore

  • Mutations (data modification)
  • Subscriptions (real-time updates)
  • Resolvers and field resolution
  • Schema validation and introspection
  • Performance optimization and caching

Summary

GraphQL eliminates over-fetching and under-fetching by letting clients specify exactly what data they need. It provides a more efficient alternative to REST for complex data requirements and modern API development.