Lesson 33 of 40
Web Development
Advanced
50 min
GraphQL APIs with Hot Chocolate
Build flexible, schema-first GraphQL APIs using Hot Chocolate 15 with VS 2026's integrated schema explorer and query analyzer.
Part 1: Schema-First with Hot Chocolate
public class Query
{
[UseProjection][UseFiltering][UseSorting]
public IQueryable<Order> GetOrders([Service] AppDbContext ctx)
=> ctx.Orders.AsQueryable();
}
{
[UseProjection][UseFiltering][UseSorting]
public IQueryable<Order> GetOrders([Service] AppDbContext ctx)
=> ctx.Orders.AsQueryable();
}
Part 2: Mutations
public class Mutation
{
public async Task<Order> CreateOrder(
CreateOrderInput input,
[Service] IOrderService service)
{
return await service.CreateAsync(input);
}
}
{
public async Task<Order> CreateOrder(
CreateOrderInput input,
[Service] IOrderService service)
{
return await service.CreateAsync(input);
}
}
Part 3: Subscriptions
public class Subscription
{
[Subscribe][Topic("OrderCreated")]
public Order OnOrderCreated([EventMessage] Order order)
=> order;
}
// Trigger from mutation:
await sender.SendAsync("OrderCreated", newOrder);
{
[Subscribe][Topic("OrderCreated")]
public Order OnOrderCreated([EventMessage] Order order)
=> order;
}
// Trigger from mutation:
await sender.SendAsync("OrderCreated", newOrder);
Part 4: DataLoader for N+1 Prevention
public class CustomerByIdDataLoader : BatchDataLoader<int, Customer>
{
protected override async Task<IReadOnlyDictionary<int,Customer>> LoadBatchAsync(
IReadOnlyList<int> keys, CancellationToken ct)
=> await _db.Customers.Where(c => keys.Contains(c.Id))
.ToDictionaryAsync(c => c.Id);
{
protected override async Task<IReadOnlyDictionary<int,Customer>> LoadBatchAsync(
IReadOnlyList<int> keys, CancellationToken ct)
=> await _db.Customers.Where(c => keys.Contains(c.Id))
.ToDictionaryAsync(c => c.Id);