ASP.NET Core  

GraphQL vs REST: Building Smarter APIs in ASP.NET Core

1. Introduction

In modern web and mobile applications, APIs play a crucial role in connecting front-end and back-end systems.
Traditionally, REST (Representational State Transfer) has been the go-to approach for building APIs. It’s simple, widely supported, and easy to understand.

However, with the growing complexity of modern applications and dynamic frontends like Angular and React, REST often causes problems like over-fetching, under-fetching, and multiple round trips to fetch related data.

To solve this, GraphQL, developed by Facebook, emerged as a flexible and efficient alternative that allows clients to request exactly what they need and nothing more.

In this article, we will explore the core differences between REST and GraphQL, understand their technical architecture in ASP.NET Core, and learn how to implement each step by step.

2. What is REST API?

REST is an architectural style that uses HTTP methods like GET, POST, PUT, DELETE to manage resources.
Each resource (like user, product, or order) is exposed through a unique URL.

Example REST endpoints

GET    /api/products
GET    /api/products/10
POST   /api/products
PUT    /api/products/10
DELETE /api/products/10

Advantages

  • Simple and widely supported

  • Easy to cache responses

  • Works with any client (browser, mobile, IoT)

Limitations

  • Over-fetching: Client gets more data than needed

  • Under-fetching: Client must call multiple endpoints for related data

  • API versioning required for changes

3. What is GraphQL?

GraphQL is a query language for APIs and a runtime for executing those queries.
It allows clients to define the exact shape and structure of the data they need from the server.

Example GraphQL query

{
  product(id: 10) {
    name
    price
    category {
      name
    }}}

This single query can replace multiple REST API calls.

The client gets only the requested fields (name, price, category.name) — no extra data.

Advantages

  • Fetch only what you need

  • No versioning required

  • Strong typing via schema

  • Great for complex UIs (like dashboards)

Limitations

  • Harder caching and monitoring

  • More complex to implement initially

  • Requires a schema definition and resolver logic

4. Technical Workflow (Flowchart)

                +-----------------------------+
                |        Client App (UI)      |
                +---------------+-------------+
                                |
                 REST           |          GraphQL
                                |
        +----------------+      |     +-------------------+
        | HTTP Endpoint  |      |     | /graphql Endpoint |
        +-------+--------+      |     +----------+--------+
                |               |                |
         +------v------+        |         +------v------+
         | Controller  |        |         | Resolver    |
         +------+------|        |         +------+------+
                |               |                |
         +------v------+        |         +------v------+
         |  Service     |       |         |  Resolver   |
         +------+-------+       |         +------+-------+
                |               |                |
         +------v------+        |         +------v------+
         |   Database   |       |         |   Database  |
         +--------------+       |         +-------------+

In REST, each endpoint corresponds to a resource (controller-action pair).

In GraphQL, there’s usually one endpoint (/graphql) that handles all types of queries and mutations via resolvers.

5. Implementing REST in ASP.NET Core

Let’s build a simple REST API using ASP.NET Core 8/9.

// Models/Product.cspublic class Product {
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
}

// Controllers/ProductController.cs
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
    private static List<Product> Products = new List<Product> {
        new Product { Id = 1, Name = "Laptop", Price = 80000, Category = "Electronics" },
        new Product { Id = 2, Name = "Shoes", Price = 2500, Category = "Fashion" }
    };

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        var product = Products.FirstOrDefault(p => p.Id == id);
        if (product == null) return NotFound();
        return Ok(product);
    }

    [HttpGet]
    public IActionResult GetAll() => Ok(Products);
}

API Response (GET /api/products/1)

{"id": 1,"name": "Laptop","price": 80000,"category": "Electronics"}

6. Implementing GraphQL in ASP.NET Core

We’ll use the HotChocolate GraphQL library for ASP.NET Core.

Step 1: Install Packages

dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.Data
dotnet add package HotChocolate.EntityFramework

Step 2: Define Schema (Type + Query)

// Models/Product.cspublic class Product {
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
}

// GraphQL/Query.cspublic class Query
{
    public List<Product> GetProducts() => new List<Product> {
        new Product { Id = 1, Name = "Laptop", Price = 80000, Category = "Electronics" },
        new Product { Id = 2, Name = "Shoes", Price = 2500, Category = "Fashion" }
    };

    public Product GetProductById(int id) => GetProducts().FirstOrDefault(p => p.Id == id);
}

Step 3: Configure Startup

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>();

var app = builder.Build();

app.MapGraphQL(); // /graphql endpoint
app.Run();

Step 4: Run GraphQL Query

Query

{
  productById(id: 1) {
    name
    price
  }}

Response

{"data": {
    "productById": {
      "name": "Laptop",
      "price": 80000
    }}}

7. Comparing REST vs GraphQL

FeatureREST APIGraphQL API
Endpoint StructureMultiple URLs (/api/products, /api/users)Single endpoint (/graphql)
Data FetchingFixed responsesClient decides structure
Over-fetchingCommon problemEliminated
Under-fetchingRequires multiple callsSingle query handles all
VersioningRequires new versions (v1, v2)Schema evolves without breaking
CachingEasy with HTTP headersComplex but possible with persisted queries
Error HandlingHTTP status codesUnified error object
Tooling SupportSwagger, PostmanGraphQL Playground, Banana Cake Pop
Performance for Small APIsBetter (simpler routing)Slight overhead
Performance for Complex APIsSlower (multiple endpoints)Better (single optimized query)

8. Use Cases and Best Practices

When to Use REST

  • Simple CRUD operations

  • Public APIs (e.g., open data)

  • Legacy systems

  • Services requiring HTTP caching

When to Use GraphQL

  • Data-heavy dashboards (multiple nested entities)

  • Microservices consuming multiple sources

  • Mobile or SPA frontends needing custom payloads

  • APIs where clients evolve rapidly

Best Practices for GraphQL

  1. Define a clear and versioned schema

  2. Avoid deeply nested queries (can cause performance issues)

  3. Use pagination and limits

  4. Implement caching (DataLoader or persisted queries)

  5. Secure resolvers with authorization policies

9. Hybrid Approach: REST + GraphQL Together

Many enterprise systems use both REST and GraphQL together.

  • REST for simple endpoints (like authentication, file uploads)

  • GraphQL for data aggregation and reporting APIs

ASP.NET Core allows hosting /api/ and /graphql endpoints in the same project, offering the best of both worlds.

Example:

app.MapControllers();   // REST
app.MapGraphQL("/graphql");  // GraphQL

10. Performance and Scalability

REST

  • Lightweight and easy to cache

  • Ideal for high-throughput APIs

  • Can cause network overhead with multiple requests

GraphQL

  • Reduces round-trips (single endpoint)

  • Slight server-side cost due to query parsing

  • Can outperform REST when optimized properly

Tip: For high-traffic GraphQL APIs, use query caching, persisted queries, and Apollo Federation for distributed systems.

11. Real-World Example: Enterprise Use Case

Imagine a CRM Dashboard built in Angular.
It needs to show user profile, orders, and messages at once.

REST Approach

  • /api/user/10

  • /api/user/10/orders

  • /api/user/10/messages

GraphQL Approach
Single query:

{
  user(id: 10) {
    name
    orders { id, total }
    messages { subject, date }}}

Result:

  • One API call instead of three

  • Smaller payload

  • Faster UI rendering

12. Conclusion

Both REST and GraphQL are powerful and relevant in today’s API-driven world.
The choice depends on project complexity, data relationships, and frontend requirements.

  • Choose REST when simplicity, caching, and legacy compatibility are priorities.

  • Choose GraphQL when flexibility, performance, and dynamic data fetching are critical.

In many enterprise solutions, a hybrid approach works best — REST for standard resources and GraphQL for advanced queries.