Real‑Time GraphQL APIs with .NET 8, Hot Chocolate, and Azure Cosmos DB

Mahmut Sarıkaya 4 dk okuma 6 Görüntülenme 0
Real‑Time GraphQL APIs with .NET 8, Hot Chocolate, and Azure Cosmos DB

Why real‑time data matters for modern apps

Imagine a logistics dashboard that must display the exact location of a delivery truck the moment it moves. A delay of even a few seconds can cause missed connections and unhappy customers. According to a 2023 Gartner survey, 68% of enterprises consider real‑time insights a critical differentiator. GraphQL subscriptions combined with Azure Cosmos DB change feed provide the low‑latency pipeline needed to push updates instantly to every connected client.

Choosing .NET 8 and Hot Chocolate for GraphQL

.NET 8 introduces native support for minimal APIs, improved performance counters, and a streamlined hosting model that reduces cold‑start times by up to 30% on Azure App Service. Hot Chocolate, the most popular GraphQL server for .NET, offers first‑class subscription support, schema‑first development, and automatic binding to dependency‑injected services. Together they let you write a type‑safe schema in C# while the runtime handles WebSocket negotiation and back‑pressure.

Preparing Azure Cosmos DB for change‑feed streaming

Cosmos DB stores JSON documents and exposes a change feed that records every insert, update, or delete. To enable real‑time notifications, create a container with partition key "/tenantId" and enable Analytical Store if you need aggregated queries later. The following Azure CLI commands provision the resource in under two minutes:

az group create --name GraphQLDemoRG --location eastus
az cosmosdb create --name GraphQLDemoCosmos --resource-group GraphQLDemoRG --capabilities EnableChangeFeed=true
az cosmosdb sql container create --account-name GraphQLDemoCosmos --resource-group GraphQLDemoRG --database-name OrdersDb --name Orders --partition-key-path "/tenantId"

Once the container is ready, the SDK can open a ChangeFeedIterator that streams new documents as they arrive.

Defining a Hot Chocolate schema with subscriptions

Start with a simple POCO that mirrors the Cosmos document:

public class Order
{
public string Id { get; set; }
public string TenantId { get; set; }
public string Status { get; set; }
public DateTime CreatedAt { get; set; }
}

The query type retrieves past orders, while the subscription type pushes newly created orders to every subscriber.

public class Query
{
public async Task<IEnumerable<Order>> GetOrdersAsync([Service] CosmosClient client)
{
var container = client.GetContainer("OrdersDb", "Orders");
var sql = "SELECT * FROM c ORDER BY c.CreatedAt DESC";
var iterator = container.GetItemQueryIterator<Order>(sql);
var results = new List<Order>();
while (iterator.HasMoreResults)
{
var response = await iterator.ReadNextAsync();
results.AddRange(response);
}
return results;
}
}

public class Subscription
{
[Subscribe]
public async IAsyncEnumerable<Order> OnOrderCreated([Service] CosmosClient client, [EnumeratorCancellation] CancellationToken ct)
{
var container = client.GetContainer("OrdersDb", "Orders");
var iterator = container.GetChangeFeedIterator<Order>(ChangeFeedStartFrom.Now(), ChangeFeedMode.AllVersions);
while (await iterator.HasMoreResultsAsync(ct))
{
foreach (var order in await iterator.ReadNextAsync(ct))
{
yield return order;
}
}
}
}

Bootstrapping the .NET 8 minimal API

The following Program.cs wires everything together. Note the use of AddInMemorySubscriptions() for development; replace with Redis or Azure SignalR for production scaling.

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.AspNetCore;
using HotChocolate.Subscriptions;
using Microsoft.Azure.Cosmos;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<CosmosClient>(sp =>
new CosmosClient(builder.Configuration["Cosmos:ConnectionString"]));
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddSubscriptionType<Subscription>()
.AddInMemorySubscriptions();

var app = builder.Build();
app.MapGraphQL();
app.Run();

Run dotnet run and navigate to http://localhost:5000/graphql. The GraphQL Playground (enabled by default in development) lets you test the orderCreated subscription with a simple WebSocket query.

Deploying to Azure App Service with WebSocket support

Azure App Service disables WebSockets on the free tier, so choose at least the B1 plan. After publishing the Docker image or the zip deploy, turn on the Web sockets toggle in the portal and set ARR Affinity to off if you plan to scale out multiple instances.

Performance tuning and monitoring

Enable Application Insights for automatic collection of request latency, GraphQL resolver duration, and Cosmos RU consumption. A typical production workload with 5 000 concurrent subscription connections consumes roughly 0.15 RU per message when the payload is under 500 bytes. Adjust the MaxMessageSize property in the Hot Chocolate server options to prevent oversized payloads.

Conclusion

By marrying .NET 8’s lean hosting model, Hot Chocolate’s robust subscription engine, and Cosmos DB’s real‑time change feed, you can deliver sub‑second data updates to any GraphQL client. The stack scales from a single dev box to a globally distributed Azure App Service farm, while keeping the codebase idiomatic C# and fully type‑safe.

Sources

Microsoft Docs – Azure Cosmos DB change feed
Hot Chocolate Documentation – Subscriptions guide
Gartner 2023 Survey – Real‑time analytics importance

Author: Mahmut Sarıkaya — sarikayadev.com

Etiketler: #dotnet 8 #graphql #hot chocolate #azure cosmos db #real-time data
Paylaş:
M

Yazar

Mahmut Sarıkaya

yazılım Geliştirici

Yorumlar

Henüz yorum yok. İlk yorumu siz yapın!

Yorum Bırakın

1 + 4 =