Sarıkaya Dev Logo

Serverless GraphQL Subscriptions in .NET 8 with Azure Functions & SignalR

Mahmut Sarıkaya 4 min read 7 Views 0
Serverless GraphQL Subscriptions in .NET 8 with Azure Functions & SignalR

Why real‑time data matters for modern APIs

Imagine a stock‑trading dashboard that must reflect price changes the instant they happen. Traditional REST endpoints force the client to poll every few seconds, wasting bandwidth and increasing latency. GraphQL subscriptions solve this by pushing updates directly to the consumer, and when you combine them with Azure Functions and SignalR, you get a fully serverless, auto‑scaling solution that runs on .NET 8.

Prerequisites and system requirements

Before you start, ensure you have the following installed: .NET SDK 8.0 (released November 2023), Azure CLI 2.45+, Visual Studio 2022 17.8 or VS Code with the C# extension, and an Azure subscription with permission to create Function Apps and SignalR Service instances. The Azure Function runtime for .NET 8 is GA as of March 2024, so you will be using the latest stable packages.

Creating the Azure Function project

Open a terminal and run the command below to scaffold a new isolated‑process Function App targeting .NET 8:

dotnet new func -n GraphQLSubscriptionsDemo --framework net8.0 --worker-runtime isolated

The template generates a Program.cs that hosts the Functions host. Replace its content with the minimal hosting model shown later, adding the GraphQL and SignalR services.

Adding HotChocolate GraphQL with subscription support

HotChocolate 13.x is the recommended GraphQL library for .NET 8. Add the packages via the CLI:

dotnet add package HotChocolate.AspNetCore\ndotnet add package HotChocolate.Subscriptions\ndotnet add package HotChocolate.AzureFunctions\ndotnet add package Microsoft.Azure.SignalR.Management

Define a simple schema that includes a subscription type. For example, a Message type with a messageAdded subscription:

public record Message(string Id, string Content, DateTimeOffset CreatedAt);public class Subscription{[Subscribe]\npublic Message OnMessageAdded([EventMessage] Message message)=>message;}

In Program.cs, register the schema and enable in‑process subscriptions:

var builder = WebApplication.CreateBuilder(args);builder.Services\n    .AddGraphQLServer()\n    .AddQueryType(d=>d.Name("Query"))\n    .AddSubscriptionType()\n    .AddInMemorySubscriptions();builder.Services\n    .AddSignalR().AddAzureSignalR();var app = builder.Build();app.MapGraphQL();app.MapHub<FunctionHub>(\"/api/hubs\");app.Run();

Configuring Azure SignalR Service

Create a SignalR resource in Azure to act as the back‑plane for subscription messages. The CLI command is:

az signalr create --name GraphQLSignalRDemo --resource-group MyResourceGroup --sku Standard_S1 --unit-count 1

Copy the ConnectionString from the Azure portal and add it to the local.settings.json of the Function App under AzureSignalRConnectionString. The Functions runtime will automatically bind this value when the host starts.

Implementing the Azure Function that publishes events

Write a simple HTTP‑triggered Function that receives a message payload and broadcasts it via the HotChocolate event sender. The function uses dependency injection to get the IEventSender service:

public class PublishMessageFunction{private readonly IEventSender _sender;public PublishMessageFunction(IEventSender sender){_sender=sender;}[Function("PublishMessage")]public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function,"post")] HttpRequestData req){var body=await new StreamReader(req.Body).ReadToEndAsync();var input=JsonSerializer.Deserialize<Message>(body);await _sender.SendAsync(input);return new OkResult();}}

This Function is stateless and can scale out to hundreds of instances without any server management, thanks to the serverless model.

Wiring SignalR to GraphQL subscriptions

HotChocolate can delegate subscription events to SignalR by using the built‑in AzureSignalR extension. Add the following line in the GraphQL configuration chain:

builder.Services.AddGraphQLServer()\n    .AddAzureSignalRSubscriptions();

Now every OnMessageAdded event is automatically forwarded to connected SignalR clients. Clients subscribe via the standard GraphQL WebSocket protocol; the underlying transport is handled by SignalR, which provides connection management, automatic reconnection, and scaling across multiple Function instances.

Testing the end‑to‑end flow

Deploy the Function App to Azure using the command:

dotnet publish -c Release -o ./publish\nfunc azure functionapp publish GraphQLSubDemo

Once deployed, use a GraphQL client such as GraphiQL or Apollo Studio to run the following subscription query:

subscription {\n  onMessageAdded {\n    id\n    content\n    createdAt\n  }\n}

In a separate terminal, invoke the HTTP function with curl to publish a new message:

curl -X POST https://.azurewebsites.net/api/PublishMessage -H "Content-Type: application/json" -d '{"id":"msg-001","content":"Hello, serverless world!","createdAt":"2026-08-28T12:00:00Z"}'

The subscription client receives the payload instantly, confirming that the serverless pipeline—Function → HotChocolate → SignalR → Client—is working as intended.

Performance tips and cost considerations

Azure SignalR Standard tier charges per connection‑hour; a typical real‑time chat app with 10,000 concurrent users costs roughly $0.08 per hour. To keep costs low, enable idle timeout (default 30 minutes) and use the InMemorySubscriptions fallback for low‑traffic environments. For production, switch to AddRedisSubscriptions() if you need cross‑region resilience.

When scaling, monitor the Function App’s “Function Execution Count” metric. .NET 8’s native AOT compilation reduces cold‑start latency to under 200 ms, making it suitable for latency‑sensitive subscriptions.

Conclusion

By marrying .NET 8, HotChocolate GraphQL, Azure Functions, and SignalR, you can deliver a truly serverless subscription experience that scales automatically, incurs only pay‑as‑you‑go costs, and requires minimal operational overhead. The pattern demonstrated here—HTTP Function publishes, GraphQL handles schema, SignalR transports events—can be extended to IoT telemetry, collaborative editing, or any scenario where real‑time data is essential.

Sources

Microsoft Azure Functions documentation, HotChocolate GraphQL official guide, Azure SignalR Service best practices

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #.NET 8 #GraphQL subscriptions #Azure Functions #SignalR #serverless
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

7 + 4 =