.NET Webhooks -Your Dummy’s Guide

Sep 22, 2023 | .NET

Webhooks, you’ve heard about them, I’ve mentioned them, but what are they? More importantly, what can they do for you as a developer? That’s what we are going to explore today: how to unleash the significant potential of webhooks within the alluring charm of the .NET environment.

The Predicament with Direct Client-Server Communication

Whenever we engage with the World Wide Web (www), we usually start with the Request-Response cycle: a client (user’s browser) sends a request to a server (website), which in turn generates a response that equips the client with the requested information. It’s an elegant, albeit simple, dance of information exchange.

But have you ever wondered how you’d get live updates from a server? Surely, you wouldn’t want your browser to repeatedly ask the server if there’s anything new, right? That would be like a child on a road trip repeatedly asking, “Are we there yet?”. It’s inefficient, annoying, and doesn’t scale well.

Such an approach, known as Polling, can be taxing on server resources since it requires continuous vigilance for any updates. So, how can we optimize this?

Say Hello to Webhooks

In comes Webhooks, the superhero of real-time communication over a network. Put simply, webhooks serve as an information delivery method that breaks away from the typical Request-Response pattern by allowing servers to directly push updates to clients!

Webhooks work like this: the client subscribes to updates on a particular subject or ‘topic’ from the server, and the server, when it has news on that topic, politely knocks on the client’s door (read: hits the client’s URL) delivering the information.

But before we dive into the deep end, let’s get to grips with some of the terminology in the world of Webhooks: Subscription, Topic, Callback, Payload, and Trigger.

Core Components of a Webhook System

Imagine you and your best friend make a pact to share comic books. How and when you would share, and what address to drop the surprises. So, buckle up because we’re going to dive into this comic pact-style adventure but in the tech world!

They call these this mysterious agreement between two friends as ‘webhooks’. And these pacts, or webhooks, have five main elements.

Subscription – A Friendship Agreement between Client and Server

Think of a subscription in a webhook system like a friendship pact between two kids in your neighborhood. It’s like saying – let’s stay in touch and share cool stuff. Here, the client and a server set up a subscription.

Just like a friendship pact, a subscription has all the necessary details of the mutual agreement. For instance, what is this friendship about? Skateboarding adventures or comic book exchanges?

Just like that, the ‘subscription’ contains the topic of interest (or what we’re choosing to share in this friendship) and the callback URL – think of it as where we’ll drop the cool stuff. It’s the client’s house – the place where they will receive all the interesting updates from the server, feeling like a birthday party where all the gifts are exactly what you dreamed of!

Topic – The Genre of our Friendship

A topic is basically what this friendship is centered around, what we agreed to share and exchange just like the comic books or skateboarding adventures in our analogy. It could be something very specific, or something broad.

Like receiving updates about the temperature in Phoenix, or getting a monthly newsletter featuring some exciting health and fitness tips, kind of like swapping letters about a specific comic series or chatting about anything fun we did lately on a skateboard!

Callback – The Address where you get your Surprises

A callback is essentially the client’s home address. In technical terms, it’s a particular URL set to receive updates from the server. Imagine if in the middle of the night, you leave a surprise gift at my doorstep, safely packed.

That’s exactly what happens here when there is an event at the server’s end. The server makes an HTTP request to the callback URL – kind of like leaving a surprise packet at a friend’s doorstep!

Payload – The Surprise Package

Ok, now the payload is the surprise package! It’s the ‘packet’ of information that the server delivers over to the client. Usually, it’s a JSON object – but let’s keep it simple!

Consider it a box filled with the cool stuff agreed upon in our friendship pact. It’s like a box that contains a new comic book issue, or maybe some tips for the latest skateboard trick.

Trigger – The Event that begins the fun

Now, the trigger is what starts all the fun. It’s the particular event or action that causes the server to send over that fun package. So let’s say – in our analogy – if we agreed to swap comic books every time a new issue comes out; the release of a new issue will be the ‘trigger’.

Just like that, the server detects the occurrence of an event of interest, and whoosh, the surprise pack is dispatched out!

Easing into Webhook Implementation

Cracking the code of webhooks, are we? Well then, buckle up for an exciting journey as we dive deep into the sea of .NET, setting up our very own webhook system! Get ready folks, we’re going to create, integrate, and trigger webhooks, all in .NET style!

Setting Up the Server

Let’s get our hands dirty and start building a simple webhook system, beginning with setting up an API endpoint. We’ll use .NET’s built-in classes for WebhookService and Subscription.

Following code snippet shows how to implement a very basic Subscribe endpoint in your API where client can register a callback URL:

// Create a record type to represent Subscription 
public record Subscription(string Topic, string Callback);

// Implement Webhook Service
public class WebhookService
{
    // Maintain a list of subscriptions
    private readonly List<Subscription> _subscriptions; 

    // Initialize subscriptions list in the constructor
    public WebhookService()
    {
        _subscriptions = new List<Subscription>();
    }

    // Function to add a new subscription to the list
    public void Subscribe(Subscription subscription)
    {
        _subscriptions.Add(subscription);
    }
}

Integrating the Trigger

Now we need an event to trigger our webhook. For testing considerations, let’s add another API endpoint that can instigate our PublishMessage method.

// Function to trigger and send message to webhook
public async Task PublishMessage(string topic, string message)
{
    // Retrieve subccriptions related to the passed topic
    var subscribedWebhooks = _subscriptions.Where(x => x.Topic == topic);

    // For each matching subscription, post a JSON message 
    // to the callback URL of the subscription
    foreach (var webhook in subscribedWebhooks)
    {
        await _httpClient.PostAsJsonAsync(webhook.Callback, message);
    }
}

Registering the Client

We are now in a position to create a client to consume our webhook. Let’s create another console application and register our first webhook

// Define the server, topic and client callback details
const string server = "http://localhost:5001";
const string callback = "http://localhost:5002/webhook-endpoint";
const string topic = "event1";
// Create a new http client
var client = new HttpClient();
// Register the client for the topic to the webhook service
await client.PostAsJsonAsync($"{server}/subscribe", new { topic, callback });

Now, we are setting up the endpoint on our client application which will receive the event notifications, making the road less traveled:

// Create the basic setup for the webhook application
var builder = WebHost.CreateDefaultBuilder(args);

// Setup the application's request handling  
builder.Configure(app =>
{
    // Setup routing
    app.UseRouting();
    // Define Endpoints
    app.UseEndpoints(endpoints =>
    {
        // Establish a POST endpoint method for callback
        endpoints.MapPost("/webhook-endpoint", RequestDelegate);
    });
});

// Build and run the application
var host = builder.Build();
await host.RunAsync();

// Define the delegate to handle requests
async Task RequestDelegate(HttpContext context)
{
    // Read the body of the incoming request as JSON
    var json = await new StreamReader(context.Request.Body).ReadToEndAsync();
   //... Additional request processing logic would go here.
}

Conclusion

Webhooks, in essence, are a triumph of asynchronous network communication. They provide a more efficient avenue for event-driven programming over traditional polling techniques. We’ve merely scratched the surface of the iceberg, and there’s so much more you can explore and implement with webhooks, such as handling security concerns or implementing retry policies.

So, fellow developers, I encourage you to befriend the superhero of real-time events — Webhooks, and embark on a journey towards cleaner, efficient code. Remember, it’s the little efficiencies that make a big difference!

Happy coding!

You May Also Like

Sign up For Our Newsletter

Weekly .NET Capsules: Short reads for busy devs.

  • NLatest .NET tips and tricks
  • NQuick 5-minute reads
  • NPractical code snippets
.