Hola folks👋👋, so in this post, I would be describing how to set up dynamic Subscriptions in Hot Chocolate. In case you don’t know what that is. Hot Chocolate is a library that allows you to easily set up a GraphQL server and Client in DotNet.
For this post, I would be creating a graphQL server that notifies clients in real time about currency rate changes of the Naira and Cedis to a Dollar. I would also use the annotation-based approach to create the schema.
Let us get started 😎
Using DotNet 7 SDK I executed the command below to create a basic minimal API template
dotnet new web
To Download the HotChocolate middleware package, I ran:
dotnet add package HotChocolate.AspNetCore --version 12.14.0
To add GraphQL server services, I added this:
builder.Services.AddGraphQLServer()
.AddSubscriptionType<Subscription>()
.AddInMemorySubscriptions().ConfigureSchema(s =>
s.ModifyOptions(o => o.StrictValidation = false));
In the snippet above I added the Subscription Type which I’m yet to create to the AddSubscriptionType method.
The o.StrictValidation ensures that the server works without the need to create QueryType since I’m focusing on subscriptions in Hot Chocolate.
Next, I added two middlewares:
app.UseWebSockets();
app.MapGraphQL();
The UseWebSockets middleware handles the initiation of a WebSocket request while the MapGraphQL middleware handles the GraphQL requests.
Next, I added the class below, to describe my currency rate update Type:
public class Currency
{
public string Code { get; set; } = default!;
public string Name { get; set; } = default!;
public double RateToADollar { get; set; }
}
Next, I added the namespaces below:
using HotChocolate.Subscriptions;
using HotChocolate.Execution;
The namespaces above import the ISourceStream, ITopicEventReceiver and ITopicEventSender interfaces
Next, I added the Subscription class:
public class Subscription
{
[SubscribeAndResolve]
public async ValueTask<ISourceStream<Currency>> OnCurrencyUpdate(string currencyCode,
[Service] ITopicEventReceiver receiver)
{
string topic = $"{currencyCode}-Updates";
return await receiver.SubscribeAsync<string, Currency>(topic);
}
}
The OnCurrencyUpdate method above provides a dynamic mechanism for creating varying subscription topics from the client. For instance, if the currencyCode argument passed in by invocation from the client is NGN, then a subscription topic of NGN-Updates is created on the server.
The code above generates the schema below:
type Subscription {
onCurrencyUpdate(currencyCode: String!): Currency!
}
For some reason, the schema wasn’t generated in Banana Cake Pop because I didn’t add the Query type.
To obtain the Subscription type above I added a dummy Query type which made the schema above to be generated. The dummy Query type isn’t relevant for this article.
Now that I have my Subscription type set, I needed a way to generate random values to be sent over to the server.
I decided to add a background service which would do just that 😎.
To do that, I used the code below to add Hosted Services support to the Service Collection:
builder.Services.AddHostedService<CurrencyUpdateService>();
Next, I created the CurrencyUpdateService Background class:
public class CurrencyUpdateService : BackgroundService
{
private readonly ITopicEventSender _eventSender;
private readonly PeriodicTimer _timer;
public CurrencyUpdateService(ITopicEventSender sender)
{
_eventSender = sender;
_timer = new PeriodicTimer(TimeSpan.FromSeconds(2));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await _timer.WaitForNextTickAsync(stoppingToken);
double randomRate = Random.Shared.NextDouble();
var nairaUpdate = new Currency
{
Code = "NGN",
Name = "Naira",
RateToADollar = randomRate * (30 - 26) + 26
};
var cedisUpdate = new Currency
{
Code = "GHS",
Name = "Cedis",
RateToADollar = randomRate * (6 - 4) + 4
};
await _eventSender.SendAsync($"NGN-Updates", nairaUpdate, stoppingToken);
await _eventSender.SendAsync($"GHS-Updates", cedisUpdate, stoppingToken);
}
}
}
In the code above, I injected the ITopicEventSender service into the background service. This service would enable sending messages or updates to subscribed clients.
What the code above does is that it sends random updates of the Naira and Cedis currency to the client.
Now from the Banana Cake Pop, I made the queries below to listen for updates for the Naira and Cedis currency
subscription {
onCurrencyUpdate(currencyCode: "NGN") {
code
name
rateToADollar
}
}
//AND
subscription {
onCurrencyUpdate(currencyCode: "GHS") {
code
name
rateToADollar
}
}
The Hot Chocolate library is pretty amazing and does a lot of magic, I also love how easy it is to set up your schema using annotations and classes in C#
To learn more about Hot Chocolate, check this.
To obtain the code used in this post check this
Thanks for reading through and I hope you liked it.
You have a gift from Binance. Gо tо withdrаwаl > https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
vss34k
Reminder: TRANSACTION 1,8268 BTC. GET > https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
7cf95o
Ticket; SENDING 1.82359 BTC. Assure =>> https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
kce3dj
Sending a transfer from us. Get => https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
w69ltm
You have a message № 592. Go - https://telegra.ph/Go-to-your-personal-cabinet-08-26?hs=a590deed1d96189ccbf33897ba098567&
ohzmzc
Notification: TRANSFER 1,8248463 BTC. Receive =>> https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
3rquhe
Ticket; TRANSFER 1,8215 bitcoin. Receive => https://telegra.ph/Go-to-your-personal-cabinet-08-25?hs=a590deed1d96189ccbf33897ba098567&
0c5xaq