GraphQL in ASP.NET Core Web API

GraphQL in ASP.NET Core Web API

ASP.NET Core Web API is commonly used to build REST APIs. REST works well for simple applications, but as modern applications grow and serve multiple clients, such as web apps, mobile apps, and dashboards, data requirements become more complex. GraphQL was introduced to solve these data-fetching problems by allowing clients to request only the data they need.

What is the default approach for building APIs in most .NET projects?

In most .NET applications, the standard and most widely used approach for building APIs is ASP.NET Core Web API, following the REST (Representational State Transfer) architectural style. REST has remained popular for many years because it is easy to understand, simple to implement, and closely aligned with how HTTP itself works.

In REST-based APIs, the backend exposes multiple endpoints, each representing a specific resource such as users, orders, or products. Each endpoint returns a predefined response structure determined entirely by the server. Standard HTTP methods like GET, POST, PUT, and DELETE are used to perform operations on these resources.

When does REST work best?

REST works especially well when the application requirements are stable and straightforward, such as:

  • The application is relatively simple and does not involve complex data relationships
  • The data requirements are clearly defined and do not change frequently
  • The number of API consumers is small or limited
  • All clients can work comfortably with fixed response structures defined by the server

In these situations, REST APIs are:

  • Easy to design because each endpoint has a clear responsibility
  • Easy to test using tools like Swagger or Postman
  • Easy to maintain because the API structure remains stable over time

However, as applications grow and become more UI-driven, REST may begin to show limitations. This is not because REST is a bad design, but because REST assumes that one fixed response structure per endpoint will work for all clients. Modern applications often require different data shapes for different screens, which REST is not naturally designed to handle.

Why does REST start feeling insufficient in modern applications?

Modern applications are no longer small or single-purpose. A single backend system today often serves multiple types of clients, such as:

  • Web applications built using React or Angular.
  • Mobile applications for Android and iOS.
  • Admin dashboards with complex views.
  • Third-party systems and partner integrations.

Each of these clients has different expectations from the API. They differ in screen size, performance constraints, bandwidth usage, and the amount of data they need.

For example:

  • A Mobile Application prefers smaller and lightweight responses to save bandwidth and improve performance
  • An Admin Dashboard usually needs deep, detailed, and nested data such as summaries, aggregates, and related entities
  • Third-party integrations often need only a small subset of data for specific use cases

REST APIs, by design, return a fixed response structure for each endpoint. While this approach works well in the early stages of an application, it becomes restrictive as the number of clients and UI variations increases.

When multiple clients and multiple screens demand different shapes of data, REST starts feeling insufficient the backend has limited flexibility. Developers are forced to either:

  • Create New Endpoints for specific screens
  • Add Response Variations or query parameters
  • Or force clients to accept Unwanted Data and make extra API calls

This rigidity is the main reason REST starts feeling insufficient in complex, modern, and UI-heavy applications.

What problems usually appear when REST APIs grow with the application?

As an application grows and the number of screens and use cases increases, REST APIs often face several practical challenges.

  • Endpoint Explosion: To support different screens and requirements, developers often create multiple specialized endpoints such as /users/summary, /users/withOrders, or /users/profileDetails. Over time, the API becomes difficult to organize, document, and maintain.
  • Multiple API Calls for One Screen: Real-world UI screens usually need combined data. For example, a single page might need user details, orders, order items, and product information. With REST, this often results in multiple API calls, and the frontend must manually merge the data.
  • Over-Fetching: Sometimes an endpoint returns a large object with many fields, even though the UI needs only a few. This leads to unnecessary data transfer, increased payload size, and affects performance.
  • Under-Fetching: In other cases, an endpoint returns insufficient data, forcing the client to make additional API calls to complete a single screen.

Together, all these problems increase network usage, slow down applications, and introduce complexity in both backend and frontend code. As a result, maintenance becomes harder, and overall development productivity decreases. For a better understanding, please look at the following image:

GraphQL in ASP.NET Core Web API

What is GraphQL?

GraphQL is an Alternative API Design Approach created specifically to solve the data-fetching problems commonly experienced with REST APIs. Instead of focusing on resources and endpoints, GraphQL focuses on Data Requirements and Relationships. GraphQL exists mainly to address problems such as:

  • Over-Fetching unnecessary data
  • Under-Fetching that requires multiple API calls
  • Multiple network requests for related data

In GraphQL, the client explicitly specifies what data it needs, and the server responds with exactly that data—no more and no less.

In simple terms:

  • REST → The server decides the response structure.
  • GraphQL → The client decides the response structure.

GraphQL does not replace ASP.NET Core or our backend architecture. It only changes how data is requested and shaped, making it highly suitable for modern UI-driven applications where data requirements vary across screens and clients. For a better understanding, please look at the following image:

What is GraphQL?

Layman Analogy

Think of your API like a restaurant:

  • REST is like ordering a fixed combo meal. You receive predefined items, even if you don’t want all of them.
  • GraphQL is like telling the waiter exactly what you want on your plate. The kitchen prepares only that order—no extra items, no waste.

The deeper meaning of this analogy:

  • REST is optimized for standardized, predefined responses
  • GraphQL is optimized for customized, client-specific data needs

Because of this, GraphQL reduces wasted data (over-fetching) and unnecessary API calls (under-fetching).

What exactly is GraphQL in ASP.NET Core Web API?

GraphQL consists of two main parts:

A Query Language

This allows clients to clearly declare what data they want. It gives clients a structured way to ask for data:

  • Which entity
  • Which fields
  • How deeply nested data should go
An Execution Engine

The GraphQL engine:

  • Validates the request against the schema
  • Executes resolvers
  • Builds the final response

GraphQL is not concerned about where your data is stored. It’s about how clients request and receive data.

In ASP.NET Core Web API, GraphQL serves as an Alternative Communication Layer (an alternative way to talk to our backend). It works smoothly with:

  • Middleware
  • Dependency injection
  • Service layer
  • Repositories
  • EF Core

So, our backend remains the same, only the API interaction style changes.

Differences Between REST and GraphQL

REST and GraphQL are two different approaches to designing APIs. REST is resource-based and endpoint-driven, while GraphQL is data-driven and query-based. For a better understanding, please look at the following image:

Differences Between REST and GraphQL

API Design Approach
  • REST is built around Resources. Each resource is exposed through a separate endpoint, and the server decides the response structure.
  • GraphQL is built around Data Requirements. It usually exposes a single endpoint, and the client specifies exactly what data it needs.
Number of Endpoints
  • REST uses Multiple Endpoints for different resources and use cases.
  • GraphQL typically uses a Single Endpoint, and operations are defined by the query rather than by the URL.
Control Over Response
  • REST is Server-Driven. The client must accept the fixed response defined by the server.
  • GraphQL is Client-Driven. The client decides which fields to return.
Over-fetching and Under-fetching
  • REST often suffers from over-fetching or under-fetching because endpoints return fixed data.
  • GraphQL avoids both by returning only the fields explicitly requested by the client.
Fetching Related Data
  • REST usually requires multiple API calls to fetch related data.
  • GraphQL can fetch related and nested data in a single request.
API Versioning
  • REST commonly uses versioning, such as/v1 and /v2, to handle changes.
  • GraphQL usually does not require versioning because new fields can be added without breaking existing clients.
Use Cases
  • REST is best suited to simple, stable APIs with predictable data requirements.
  • GraphQL is better suited for complex, UI-driven applications with multiple clients and changing data requirements.
Which one is better?

Neither is universally better. REST works well for simple, stable APIs, while GraphQL is better suited to complex, data-driven applications with multiple frontends. REST is endpoint-centric and server-controlled, while GraphQL is query-centric and client-controlled.

Core Building Blocks of GraphQL:

GraphQL is built around five core building blocks that define how data flows through the system:

  1. Schema – Defines the contract between client and server.
  2. Types and Fields – Describe the data structure.
  3. Queries – Used to read data.
  4. Mutations – Used to modify data.
  5. Subscriptions – Used for real-time updates

For a better understanding, please look at the following image:

Core Building Blocks of GraphQL

Together, these components define what data is available, how it can be accessed, and how it flows through the system. A simple way to imagine this:

  • Schema → Menu
  • Types & Fields → Dishes and Ingredients
  • Queries & Mutations → Order slip
  • Subscriptions → Live updates (“notify me when it’s ready”)
What is a Schema in GraphQL?

The schema is the core foundation of GraphQL. It acts as a strongly typed contract between the client and the server. It defines:

  • What types exist (User, Order, Product)
  • What fields are available on each type
  • What operations can the client perform
  • What inputs are valid
  • How types are related to each other

Before any request is executed, GraphQL validates it against the schema. If a client requests a field that does not exist or provides invalid input, the request is rejected immediately. You can imagine the schema like the restaurant menu. If an item is not on the menu, you can’t order it.

What are Types and Fields?

GraphQL organizes data into types, and each type contains fields.

  • Types represent Entities or Models (User, Order, Product, Payment, etc.)
  • Fields represent properties inside a Type (Id, Name, Email, Price)

GraphQL supports different kinds of types, including:

  • Object types (complex structures like User, Order)
  • Scalar types (string, int, boolean)
  • Enum types (fixed options like OrderStatus)
  • List types (collections like a list of orders, a list of products inside an order)
  • Nullable/non-null fields (optional vs mandatory values)
What are Queries in GraphQL?

Queries are used to Read Data, similar to a REST GET request. But the key advantage is that queries allow Field-Level Control. The client decides:

  • Which fields should come back
  • How deeply nested data should be included

For example, give me only my name, email, and the last 5 orders. This makes queries perfect for UI-driven screens that need different shapes of data.

What are Mutations in GraphQL?

Mutations are used to change data, similar to REST POST, PUT, and DELETE operations. They support:

  • Creating data (POST)
  • Updating data (PUT/PATCH)
  • Deleting data (DELETE)

A well-designed mutation usually returns:

  • The created or updated data
  • Success or status information
  • Validation or business error details

For example, place my order and give me confirmation details.

What are Subscriptions in GraphQL?

Subscriptions enable real-time communication between the server and the client. Instead of repeatedly requesting updates, the server automatically pushes data when something changes. Common use cases include:

  • Live notifications
  • Chat applications
  • Real-time dashboards (stocks, orders, delivery tracking)

For example, live cricket score updates—you don’t have to refresh; they come automatically.

What is BFF (Backend for Frontend)?

BFF stands for Backend for Frontend. It is a dedicated backend layer designed to serve a specific frontend application. In modern systems, we usually have multiple frontends such as web apps, mobile apps, and admin dashboards. Even though they use the same business data, their data requirements differ significantly.

What does a BFF do?

A Backend for Frontend sits between the frontend and backend microservices and focuses only on preparing data for the UI.

A BFF typically:

  • Communicates with multiple microservices
  • Fetches data from different backend systems
  • Combines and transforms data
  • Shapes the response exactly as required by the UI
  • Hides backend complexity from frontend developers

From the frontend’s point of view, the BFF is the only backend it needs to talk to.

Layman Analogy

Think of a restaurant:

Microservices = Kitchen Departments
  • Veg section
  • Dessert section
  • Billing section

Each kitchen department prepares only its own items and does not concern itself with the final customer order.

API Gateway = Security Guard + Traffic Controller
  • Controls who can enter
  • Routes requests to the right place
  • Enforces rules like authentication and rate limiting
BFF = Personal Waiter
  • Takes your exact order
  • Understands what you want and how you want it served
  • Talks to multiple kitchen counters
  • Collects everything
  • Bring it together on a single plate

The customer (frontend) never deals with the kitchen directly—only with the waiter (BFF).

Conclusion: Why GraphQL Matters?

GraphQL is an alternative API approach that focuses on flexible and efficient data fetching. It helps avoid common REST problems such as over-fetching, under-fetching, and multiple API calls. GraphQL works smoothly with ASP.NET Core without changing existing backend logic. When used in the right scenarios, it makes APIs more efficient and easier to use for modern applications.

Leave a Reply

Your email address will not be published. Required fields are marked *