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
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
| Feature | REST API | GraphQL API |
|---|
| Endpoint Structure | Multiple URLs (/api/products, /api/users) | Single endpoint (/graphql) |
| Data Fetching | Fixed responses | Client decides structure |
| Over-fetching | Common problem | Eliminated |
| Under-fetching | Requires multiple calls | Single query handles all |
| Versioning | Requires new versions (v1, v2) | Schema evolves without breaking |
| Caching | Easy with HTTP headers | Complex but possible with persisted queries |
| Error Handling | HTTP status codes | Unified error object |
| Tooling Support | Swagger, Postman | GraphQL Playground, Banana Cake Pop |
| Performance for Small APIs | Better (simpler routing) | Slight overhead |
| Performance for Complex APIs | Slower (multiple endpoints) | Better (single optimized query) |
8. Use Cases and Best Practices
When to Use REST
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
Define a clear and versioned schema
Avoid deeply nested queries (can cause performance issues)
Use pagination and limits
Implement caching (DataLoader or persisted queries)
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:
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.