Published on
Last Updated on
Estimated Reading Time: 2 min
GraphQL offers us real-time capabilities to notify us when a specific event happens.
In this tutorial, we will add subscriptions to our graphql server. We will create an onPing
event that will send notifications whenever we ping the server with an input string.
We will also use Redis that runs in a docker container, and see how we can listen to the events in a Redis command shell.
Running Redis using docker
docker run -d --name=redis-graphql -p 6379:6379 redis:6.0-alpine
Adding a Subscription
We will add a new class Subscription which will have our onPing
event.
public class Subscription : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor.Field("onPing")
.Type<NonNullType<StringType>>()
.Resolve(ctx => ctx.GetEventMessage<string>())
.Subscribe(async ctx => await ctx.Service<ITopicEventReceiver>().SubscribeAsync<string, string>("onPing", ctx.RequestAborted));
}
}
- Line 5: The topic for the subscription.
- Line 7: Gets the message payload.
- Line 8: Subscribes to the pub/sub system
To use subscriptions, we need to add the WebSockets middleware to our request pipeline.
// Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseWebSockets();
}
Note: Middleware order is important with .NET Core, so this middleware needs to come before the GraphQL middleware.
Next, We need to register our subscriptions and set up the Redis subscription provider in the Startup class.
public void ConfigureServices(IServiceCollection services)
{
var options = new ConfigurationOptions
{
EndPoints = { "localhost:6379" },
};
services.AddGraphQLServer()
.AddSubscriptionType<Subscription>();
.AddRedisSubscriptions(_ => ConnectionMultiplexer.Connect(options));
}
Note: Redis is on port 6379 by default.
Publishing the event
Our mutation needs to use ITopicEventSender
to send messages to the underlying pub/sub system.
public class Mutation : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor.Field("ping")
.Type<NonNullType<StringType>>()
.Argument("payload", des => des.Type<NonNullType<StringType>>())
.Resolve(
async ctx =>
{
var input = ctx.ArgumentValue<string>("payload");
await ctx.Service<ITopicEventSender>().SendAsync("onPing", input);
return input;
});
}
}
- Line 13:: "onPing" is the topic we want to publish, and input is our payload.
Testing
We can start an Interactive Shell for the Redis Docker Container.
docker exec -it redis-graphql redis-cli
Next, we can subscribe to the onPing channel using the subscribe command.
subscribe onPing
In Insomnia (or your IDE of choice), add the following mutation.
mutation {
ping(payload: "hello")
}
On execution, we should see the following responses.
In the shell, we can see the event on Redis.
Demo Project
There is a demo project you can check out over on GitHub.