Implement GraphQL Subscriptions in .NET 8 Minimal APIs with HotChocolate and Azure SignalR

Mahmut Sarıkaya 4 dk okuma 8 Görüntülenme 0
Implement GraphQL Subscriptions in .NET 8 Minimal APIs with HotChocolate and Azure SignalR

Why real‑time data matters in modern .NET apps

Imagine a dashboard that updates the moment a new order is placed, or a chat window that reflects messages instantly. According to a 2023 Stack Overflow survey, 62% of developers consider real‑time features a top priority for new projects. In the .NET ecosystem, achieving that latency‑free experience often means combining GraphQL subscriptions with a reliable transport layer.

Understanding GraphQL subscriptions in .NET 8

GraphQL subscriptions are a push‑based extension of the query language. Instead of polling, the client opens a persistent connection and receives events as soon as the server publishes them. .NET 8 introduces native support for Minimal APIs, letting you declare endpoints with just a few lines of code. HotChocolate, the most widely adopted GraphQL server for .NET, ships with a subscription engine that can be backed by Azure SignalR Service for horizontal scaling.

Setting up the project skeleton

First, ensure you have .NET 8 SDK (version 8.0.100 or later) and an Azure subscription. Open a terminal and run the following commands:

dotnet new web -minapi -o GraphQLSubscriptionDemo
cd GraphQLSubscriptionDemo
dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.Subscriptions
dotnet add package Microsoft.Azure.SignalR

The template creates a Program.cs file that already hosts a Minimal API host. You will extend this file with GraphQL services.

Adding HotChocolate and enabling subscriptions

Define a simple query and a subscription type. Place the classes in a new folder called GraphQL:

namespace GraphQLSubscriptionDemo.GraphQL;
public class Query
{
    public string Hello() => "Hello from .NET 8";
}
public class Subscription
{
    [Subscribe]
    public string OnMessage([EventMessage] string message) => message;
}

Now register HotChocolate in Program.cs. The AddSignalRSubscriptions() call tells HotChocolate to use SignalR as the transport.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR().AddAzureSignalR(builder.Configuration["AzureSignalR:ConnectionString"]);
builder.Services.AddGraphQLServer()
    .AddQueryType<Query>()
    .AddSubscriptionType<Subscription>()
    .AddInMemorySubscriptions()
    .AddSignalRSubscriptions();
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapGraphQL();
    endpoints.MapHub<Microsoft.AspNetCore.SignalR.Hub>("/graphql");
});
app.Run();

Notice the use of AddInMemorySubscriptions() for local development; in production you would replace it with a distributed store such as Redis.

Integrating Azure SignalR Service as transport

Azure SignalR Service handles connection scaling automatically. Create a SignalR resource in the Azure portal, copy the connection string, and add it to appsettings.json:

{
  "AzureSignalR": {
    "ConnectionString": "Endpoint=https://your-signalr.service.signalr.net;AccessKey=...;Version=1.0;"
  }
}

The earlier AddAzureSignalR call reads this value, registers the service, and injects a hub endpoint that HotChocolate will use for subscription traffic.

Testing the subscription endpoint

Run the application (dotnet run) and open a GraphQL client such as Banana Cake Pop or GraphQL Playground. Execute the following subscription query:

subscription {
  onMessage
}

In a separate terminal, simulate a publish event using the HotChocolate request executor:

using var scope = app.Services.CreateScope();
var executor = scope.ServiceProvider.GetRequiredService<IRequestExecutor>();
await executor.ExecuteAsync("mutation { publishMessage(message: \"Hello SignalR\") }");

The client receives Hello SignalR instantly, confirming that the subscription pipeline—from Minimal API, through HotChocolate, to Azure SignalR—is functional.

Performance tips and common pitfalls

1. **Connection limits** – Azure SignalR defaults to 1,000 concurrent connections per unit. Scale out by adding more units or enabling the “Serverless” tier for burst traffic.
2. **Message size** – Keep payloads under 32 KB; larger messages are split and may increase latency.
3. **Authentication** – Use Azure AD or JWT validation on the SignalR hub to prevent unauthorized subscription access.
4. **Distributed subscriptions** – Switch from AddInMemorySubscriptions() to AddRedisSubscriptions() when you run multiple API instances behind a load balancer.

Conclusion

By leveraging .NET 8 Minimal APIs, HotChocolate’s subscription engine, and Azure SignalR Service, you can deliver true real‑time experiences with minimal boilerplate. The approach scales from a single dev machine to a multi‑region cloud deployment, while keeping the codebase clean and type‑safe. Start with the steps above, monitor connection metrics in Azure, and iterate on your schema to unlock the full power of GraphQL subscriptions in the .NET world.

Sources

  • Microsoft Docs – ASP.NET Core Minimal APIs
  • HotChocolate GraphQL Documentation
  • Azure SignalR Service Overview

Author: Mahmut Sarıkaya — sarikayadev.com

Etiketler: #.NET 8 #GraphQL subscriptions #HotChocolate #Azure SignalR Service #Minimal APIs
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

8 + 4 =