| gRPC APIs in .NET Core :👈 | 👉:Access Token Pattern |
GraphQL with .NET Core |
🌐 GraphQL with .NET Core
GraphQL is a query language for APIs and a server-side runtime for executing those queries. In contrast to traditional REST APIs, which rely on multiple, fixed endpoints, GraphQL typically uses a single endpoint. This allows clients to request exactly the data they need, addressing issues like over-fetching (getting too much data) and under-fetching (making multiple requests for related data).
In .NET Core, several libraries facilitate GraphQL implementation. One of the most popular is Hot Chocolate, a feature-rich and developer-friendly framework that integrates seamlessly with ASP.NET Core.
📦 Prerequisites
- .NET 6 or later
- NuGet packages:
HotChocolate.AspNetCore,HotChocolate.Data - IDE like Visual Studio or VS Code
🧪 Steps to Create a GraphQL API
1. Create a New Project
dotnet new webapi -n GraphQLDemo
2. Install Hot Chocolate
dotnet add package HotChocolate.AspNetCore
3. Define a Model
public class Book {
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}
4. Create a Query Class
public class Query {
public Book GetBook() => new Book { Id = 1, Title = "GraphQL Guide", Author = "Shivshanker" };
}
5. Configure GraphQL in Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>();
var app = builder.Build();
app.MapGraphQL();
app.Run();
6. Run and Test
Navigate to https://localhost:{port}/graphql and use the Banana Cake Pop UI to test queries like:
{
book {
id
title
author
}
}
🛠️ Example: Implementing GraphQL with Hot Chocolate in .NET Core
1️⃣ Set up the project
First, create a new ASP.NET Core Web API project.
2️⃣ Install NuGet packages
dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.Data.EntityFramework
3️⃣ Define your data models
// Models/Product.cs
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
4️⃣ Implement the data context and service
// Data/ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
public DbSet<Product> Products { get; set; }
}
// Services/ProductService.cs
public class ProductService
{
private readonly ApplicationDbContext _context;
public ProductService(ApplicationDbContext context) => _context = context;
public IQueryable<Product> GetProducts() => _context.Products;
}
5️⃣ Define the GraphQL types and schema
// GraphQL/Query.cs
using HotChocolate.Data;
public class Query
{
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Product> GetProducts([Service] ProductService service)
{
return service.GetProducts();
}
}
6️⃣ Configure the GraphQL server in Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services for GraphQL
builder.Services.AddPooledDbContextFactory<ApplicationDbContext>(opt =>
opt.UseInMemoryDatabase("ProductsDb"));
builder.Services.AddScoped<ProductService>();
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddProjections()
.AddFiltering()
.AddSorting()
.AddInMemorySubscriptions(); // For real-time functionality
var app = builder.Build();
// Seed data
await using (var scope = app.Services.CreateAsyncScope())
{
var context = scope.ServiceProvider.GetRequiredService<IDbContextFactory<ApplicationDbContext>>().CreateDbContext();
context.Products.AddRange(
new Product { Id = 1, Name = "Laptop", Price = 1200 },
new Product { Id = 2, Name = "Keyboard", Price = 75 }
);
await context.SaveChangesAsync();
}
app.MapGraphQL();
app.Run();
7️⃣ Test with the built-in IDE
Run the application and navigate to the /graphql endpoint. Hot Chocolate provides a browser-based IDE (Banana Cake Pop) where you can explore the schema and execute queries.
query {
products(where: { name: { contains: "key" } }, first: 10) {
name
price
}
}
✅ Advantages
- Reduced over- and under-fetching: Clients get precisely the data they need in a single request, which saves bandwidth and reduces latency.
- Rapid feature evolution: Adding new fields does not create breaking changes for existing clients.
- Powerful aggregation: Avoids the "N+1" problem common in REST APIs.
- Strongly typed and self-documenting: The schema provides a single source of truth for all API capabilities.
- Real-time updates: Subscriptions enable robust real-time functionality over WebSockets.
⚠️ Disadvantages
- Increased complexity: Setup and server-side logic are more complex than basic REST APIs.
- Caching challenges: Traditional HTTP caching is difficult; client-side or server-side strategies are required.
- Security risks: Deeply nested queries can expose the server to DoS attacks; implement complexity analysis and depth limiting.
- Steeper learning curve: Teams need to learn GraphQL-specific concepts like schemas, resolvers, and mutations.
❌ Limitations
- Steeper learning curve than REST
- Complex caching and error handling
- Overhead for simple CRUD APIs
📌 When to Use
- Complex applications with diverse clients.
- High read-to-write ratio applications.
- Microservices architecture as a "gateway".
- Rapidly evolving frontend requirements.
❌ When Not to Use
- Simple, fixed-data applications: REST may be simpler and easier to cache.
- Small teams or startups: Added complexity may not be worthwhile.
- High-performance, low-latency internal APIs: gRPC may be more performant.
💡 Best Practices and Tips
- Design a strong schema with consistent naming and clear descriptions.
- Use DataLoader pattern to solve the N+1 problem.
- Implement query complexity analysis and depth limiting.
- Enforce authentication and authorization in resolvers.
- Use Entity Framework's IQueryable with projections and filtering.
- Use fragments to reuse parts of complex or repetitive queries.
⚠️ Precautions
- Secure introspection: Restrict or disable in production.
- Watch for performance bottlenecks with complex relationships.
- Handle errors gracefully: GraphQL returns 200 OK for all responses; parse payload for errors.
- Decide on client-side caching using libraries like Apollo Client.
| gRPC APIs in .NET Core :👈 | 👉:Access Token Pattern |