GraphQL Subscriptions in ASP.NET Core

December 01, 2021 by Anuraj

AspNetCore GraphQL DotNet6

This post is about implementing Subscriptions in GraphQL. Subscriptions are a GraphQL feature that allows a server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets. The subscription type is almost implemented like a query. Most cases subscriptions are raised through mutations, but subscriptions could also be raised through other backend systems.

First we need to implement a Subscription class, like this.

public class Subscription
{
    [Subscribe]
    public Link OnCreateLink([EventMessage] Link link) => link;
}

The Subscribe attribute will make the method support subscription. And Subscription works using WebSockets, so we need to add WebSocket also to the pipeline. Also we need to modify the Subscription type to the GraphQL server with the subscription storage. In this example, I am using in memory storage, you can use Redis as well. Here is the updated code.

builder.Services.AddGraphQLServer()
    .AddQueryType<Query>()
    .AddProjections()
    .AddFiltering()
    .AddSorting()
    .AddMutationType<Mutation>()
    .AddSubscriptionType<Subscription>()
    .AddInMemorySubscriptions();

var app = builder.Build();
app.UseWebSockets();

And you can trigger the event using the ITopicEventSender instance which will be injected to the pipeline. We can modify the Mutation class - AddLink method like this.

public async Task<LinkOutput> AddLink(LinkInput linkInput,
    [ScopedService] BookmarkDbContext bookmarkDbContext, [Service] ITopicEventSender sender)
{
    if (string.IsNullOrEmpty(linkInput.Url))
    {
        throw new ArgumentNullException(nameof(linkInput.Url));
    }

    var link = new Link
    {
        Url = linkInput.Url,
        Title = linkInput.Title,
        Description = linkInput.Description,
        ImageUrl = linkInput.ImageUrl,
        CreatedOn = DateTime.UtcNow
    };
    bookmarkDbContext.Links.Add(link);
    await bookmarkDbContext.SaveChangesAsync();
    await sender.SendAsync(nameof(Subscription.OnCreateLink), link);
    return new LinkOutput(true, "Link created successfully", link.Id, link.Url,
        link.Title, link.Description, link.ImageUrl, link.CreatedOn);
}

Now we are ready to run the application. Since we are not discussed the client applications, we can use the Banana Cake Pop client app to test the subscription. Here is the Subscription schema details.

Graph QL endpoint - Subscription Schema

You can write following GraphQL subscription code in the operations tab.

subscription {
  onCreateLink {
    id
    title
    description
  }
}

And then click on the Run button. It will wait for the event, button will change to cancel - showing a progress circle, like this.

Graph QL endpoint - Subscription

You can test it using a new browser window - one for subscription - right side - Chrome and another for mutation - left side Edge. Execute the Subscription code by clicking on the Run button and then execute the mutation code. This will create a link and which will send the event using ITopicEventSender instance SendAsync method. Here is the screen capture.

Graph QL endpoint - Subscription in Action

The subscription type in GraphQL is used to add real-time capabilities to our applications. Clients can subscribe to events and receive the event data in real-time, as soon as the server publishes it.

You can find more details about Subscriptions in HotChocolate here

You can find the source code in GitHub

Happy Programming :)

Copyright © 2024 Anuraj. Blog content licensed under the Creative Commons CC BY 2.5 | Unless otherwise stated or granted, code samples licensed under the MIT license. This is a personal blog. The opinions expressed here represent my own and not those of my employer. Powered by Jekyll. Hosted with ❤ by GitHub