Skip to content

Commit

Permalink
Merge pull request #13 from deveel/10-aspnet-core-middleware
Browse files Browse the repository at this point in the history
ASP.NET Core Receiver Middleware
  • Loading branch information
tsutomi authored Apr 19, 2023
2 parents abce0bb + 1a9f733 commit 771e80e
Show file tree
Hide file tree
Showing 75 changed files with 4,593 additions and 1,283 deletions.
23 changes: 15 additions & 8 deletions Deveel.Webhooks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.Model", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.XUnit", "test\Deveel.Events.Webhooks.XUnit\Deveel.Webhooks.XUnit.csproj", "{CF170566-4653-4E7A-AC54-5A1F7594B71F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.Receiver", "src\Deveel.Webhooks.Receiver\Deveel.Webhooks.Receiver.csproj", "{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks", "src\Deveel.Webhooks\Deveel.Webhooks.csproj", "{6435EBAE-5E0A-446D-B4E4-D75FE89DFC99}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.Service", "src\Deveel.Webhooks.Service\Deveel.Webhooks.Service.csproj", "{D2A74CD1-202E-4F64-BAD8-88F37EB3805A}"
Expand All @@ -23,7 +21,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{57F6404B-1FC
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{07F23FF6-2FE1-4072-BF37-9238E3750AA1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deveel.Webhooks.Receiver.XUnit", "test\Deveel.Webhooks.Receiver.XUnit\Deveel.Webhooks.Receiver.XUnit.csproj", "{4BC8323C-74F7-407A-8A5A-EA595B5C5585}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.Receiver.XUnit", "test\Deveel.Webhooks.Receiver.XUnit\Deveel.Webhooks.Receiver.XUnit.csproj", "{4BC8323C-74F7-407A-8A5A-EA595B5C5585}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Webhooks.Receiver.TestApi", "test\Deveel.Webhooks.Receiver.TestApi\Deveel.Webhooks.Receiver.TestApi.csproj", "{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deveel.Webhooks.Receiver.AspNetCore.NewtonsoftJson", "src\Deveel.Webhooks.Receiver.AspNetCore.NewtonsoftJson\Deveel.Webhooks.Receiver.AspNetCore.NewtonsoftJson.csproj", "{F23E99C7-8228-4AEE-894B-CAA303686239}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -39,10 +41,6 @@ Global
{CF170566-4653-4E7A-AC54-5A1F7594B71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF170566-4653-4E7A-AC54-5A1F7594B71F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF170566-4653-4E7A-AC54-5A1F7594B71F}.Release|Any CPU.Build.0 = Release|Any CPU
{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4}.Release|Any CPU.Build.0 = Release|Any CPU
{6435EBAE-5E0A-446D-B4E4-D75FE89DFC99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6435EBAE-5E0A-446D-B4E4-D75FE89DFC99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6435EBAE-5E0A-446D-B4E4-D75FE89DFC99}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -67,20 +65,29 @@ Global
{4BC8323C-74F7-407A-8A5A-EA595B5C5585}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BC8323C-74F7-407A-8A5A-EA595B5C5585}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BC8323C-74F7-407A-8A5A-EA595B5C5585}.Release|Any CPU.Build.0 = Release|Any CPU
{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F}.Release|Any CPU.Build.0 = Release|Any CPU
{F23E99C7-8228-4AEE-894B-CAA303686239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F23E99C7-8228-4AEE-894B-CAA303686239}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F23E99C7-8228-4AEE-894B-CAA303686239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F23E99C7-8228-4AEE-894B-CAA303686239}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9D710920-2A08-466C-94F0-3FD90E752A20} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{CF170566-4653-4E7A-AC54-5A1F7594B71F} = {07F23FF6-2FE1-4072-BF37-9238E3750AA1}
{954A1901-CD16-4DD0-A6F3-D0D7E7F1B9A4} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{6435EBAE-5E0A-446D-B4E4-D75FE89DFC99} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{D2A74CD1-202E-4F64-BAD8-88F37EB3805A} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{9796303D-5EFF-4942-A563-6B53C4FE6904} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{6E1CC992-53F1-4536-96C5-751C8AFBD015} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{69EA8584-6336-4A62-BE73-DE04DC6EE8E1} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
{4BC8323C-74F7-407A-8A5A-EA595B5C5585} = {07F23FF6-2FE1-4072-BF37-9238E3750AA1}
{CBAC02DA-EFF9-4458-99A2-DAF7ACFE607F} = {07F23FF6-2FE1-4072-BF37-9238E3750AA1}
{F23E99C7-8228-4AEE-894B-CAA303686239} = {57F6404B-1FCC-473F-A189-ABC9D640CC0E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E682A9F5-43D7-4D4C-82EA-953545B8F4DE}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Although this integration model is widely adopted by major service providers (li
Anyway, a typical implementation consists of the following elements:

* Webhooks are transported through _HTTP POST_ callbacks
* The webhook payload is represented as a JSON object (or alternatively as XML or Form)
* The webhook payload is formatted as a JSON object (or alternatively, in lesser common scenarios, as XML or Form)
* The webhook payload includes properties that describe the type of event and the time-stamp of the occurrence
* An optional signature in the header of the request or a query-string parameter ensures the authenticity of the caller

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright 2022 Deveel
extensions: .cs
// Copyright 2022-2023 Deveel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -11,12 +12,3 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;

namespace Deveel.Webhooks {
public enum WebhookSignatureLocation {
Header,
QueryString
}
}
6 changes: 5 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

# Deveel Webhooks Documentation

Here you can find a documentation of the `Deveel Webhooks` framework, to help you getting started with the libraries and functions that compose it and to understand how it works.


## Basic Concepts

| Concept | Description |
| Topic | Description |
| ---------------------------------------------------- | ------------------------------------------ |
| **[Webhook](concept_webhook.md)** | What is it a 'Webhook' and why I need it? |
| **[Subscriptions](concept_webhook_subscription.md)** | How does a subscription to an event works? |
Expand All @@ -32,6 +35,7 @@
| **[Basic Usage - Sending Webhooks](basic_usage_send.md)** | Manually sending webhooks (no subscriptions) |
| **[Basic Usage - Subscription Management](basic_usage_management.md)** | Manage subscriptions to events (no sending) |
| **[Basic Usage - Notify Webhooks](basic_usage_notify.md)** | Notify webhooks subscribers (management, transformations and sending) |
| **[Basic Usage - Receiving Webhooks](basic_usage_receive.md)** | Receive webhooks from external sources |

## Extending

Expand Down
128 changes: 128 additions & 0 deletions docs/basic_usage_receive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Receive Webhooks from External Sources

## Installations

When receiving webhooks from external sources, you can use the `Deveel.Webhooks.Receiver.AspNetCore` library, that allows the registration of a webhook receiver in an ASP.NET Core application.

To enable this function you must first install the NuGet package:

```bash
dotnet add package Deveel.Webhooks.Receiver.AspNetCore
```


## Registering the Webhook Receiver

Then, in the `Startup` class of your application, you can register the webhook receiver as follows:

```csharp
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddWebhooks<MyWebhook>();
}
}
```

Or alternatively, if you are using the mininal API pattern, you can use the following code:

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddWebhooks<MyWebhook>();
```

This simple call registers the webhook receiver in the application, and allows to receive webhooks of type `MyWebhook`: receivers are segregated by the type of webhook they can handle, and you can register multiple receivers for different types of webhooks.

By default the registration of the webhook receiver adds a set of default services, that are required to handle the webhooks, such as the `IWebhookReceiver<MyWebhook>`, `IWebhookHandler<MyWebhook>`, `IWebhookJsonParser<MyWebhook>` and a default set of options: you can control further the services and configurations by using the builder instance returned by the `AddWebhooks` method.

## Receiving Webhooks - Using Controllers

Following the registration of the webhook receiver, you can receive webhooks by using the `IWebhookReceiver<MyWebhook>` service, that is registered in the application, if you want to handle the receive process directly.

This approach is typical in MVC APIs that implement the request processing in the controller, and can be used as follows:

```csharp
namespace Demo {
[ApiController]
[Route("webhook")]
public class WebhookController : ControllerBase {
private readonly IWebhookReceiver<MyWebhook> webhookReceiver;
private readonly IWebhookHandler<MyWebhook> webhookHandler;

public WebhookController(IWebhookReceiver<MyWebhook> webhookReceiver, IWebhookHandler<MyWebhook> webhookHandler) {
this.webhookReceiver = webhookReceiver;
this.webhookHandler = webhookHandler;
}

[HttpPost]
public async Task<IActionResult> ReceiveWebhook() {
var result = await webhookReceiver.ReceiveAsync(Request, HttpContext.RequestAborted);
if (!result.IsValid)
return BadRequest(result.Error);

var webhook = result.Webhook;
await webhookHandler.HandleAsync(webhook, HttpContext.RequestAborted);

return Ok();
}
}
}
```

Mind that in the above scenario you must also inject the `IWebhookHandler<MyWebhook>` service, that is used to handle the received webhook.

## Receiving Webhooks - Using Middleware

Alternatively the `Deveel.Webhooks.Receiver.AspNetCore` library provides a middleware that can be used to receive webhooks, and handle them automatically.

To use the middleware, you must first register it in the `Startup` class of your application:

```csharp
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddWebhooks<MyWebhook>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
app.UseWebhooks<MyWebhook>("/webhook");
}
}
```

If you are using the minimal API pattern, you can use the following code:

```csharp

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWebhooks<MyWebhook>();

var app = builder.Build();

app.UseWebhooks<MyWebhook>("/webhook");

app.Run();
```

The above code registers the middleware in the application, and allows to receive webhooks of type `MyWebhook` at the `/webhook` endpoint, using the configurations defined when registering the receiver,

The middlware will automatically scan for all the registered webhook receivers, and will handle the received webhooks by using the `IWebhookHandler<MyWebhook>` service.

The middleware design allows to handle the webhooks without any prior registered handler, by specifying an handling delegate in the `UseWebhooks` method:

```csharp
[...]

app.UseWebhooks<MyWebhook>("/webhook", (context, webhook, cancellationToken) => {
// Handle the webhook here
});
```

Or a alternatively a synchronous handling delegate:

```csharp
[...]

app.UseWebhooks<MyWebhook>("/webhook", (context, webhook) => {
// Handle the webhook here
});
```
22 changes: 11 additions & 11 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Getting Started

The overall design of this little framework is open and extensible (implementing the traditional [Open-Closed Principle](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)), that means base contracts can be extended, composed or replaced.
The overall design of this framework is open and extensible (implementing the traditional [Open-Closed Principle](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)), that means base contracts can be extended, composed or replaced.

It is possible to use its components as they are provided, or use the base contracts to extend single functions, while still using the rest of the provisioning.

Expand All @@ -38,13 +38,13 @@ Or by editing your `.csproj` file and adding a `<PackageReference>` entry.
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>ne5.0</TargetFramework>
...

</PropertyGroup>

<ItemGroup>
<PackageReference Include="Deveel.Webhooks" Version="1.0.1-alpha1" />
<PackageReference Include="Deveel.Webhooks" Version="1.1.6" />
...
</ItemGroup>
</Project>
Expand All @@ -56,17 +56,17 @@ This provides all the functions that are needed to send webhooks to a given dest

The libraries currently provided by the framework are the following:

| Library | Description | NuGet |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **Deveel.Webhooks.Model** | The foundation library that defines the webhooks information model | [Package](https://www.nuget.org/packages/Deveel.Webhooks.Model/) |
| **Deveel.Webhooks** | Provides the foundation contracts of the webhook service and basic implementations for the sending functions | [Package](https://www.nuget.org/packages/Deveel.Webhooks/) |
| **Deveel.Webhooks.Service** | Implements the functions to manage and resolve webhook subscriptions | [Package](https://www.nuget.org/packages/Deveel.Webhooks.Service/) |
| **Deveel.Webhooks.Service.MongoDb** | An implementation of the webhoom management data layer that is backed by [MongoDB](https://mongodb.com) databases | [Package](https://www.nuget.org/packages/Deveel.Webhooks.MongoDb/) |
| **Deveel.Webhooks.DynamicLinq** | The webhook subscription filtering engine that uses the [Dynamic LINQ](https://dynamic-linq.net/) expressions | [Package](https://www.nuget.org/packages/Deveel.Webhooks.DynamicLinq/) |
| Library | Description | NuGet | GitHub (prerelease) |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |---------------------|
| **Deveel.Webhooks** | Provides the foundation contracts of the webhook service and basic implementations for the sending functions | ![Nuget](https://img.shields.io/nuget/dt/Deveel.Webhooks?label=Deveel.Webhooks&logo=nuget) | [![GitHub](https://img.shields.io/static/v1?label=Deveel.Webhooks&message=Pre-Release&color=yellow&logo=github)](https://github.com/deveel/deveel.webhooks/pkgs/nuget/Deveel.Webhooks) |
| **Deveel.Webhooks.Service** | Implements the functions to manage and resolve webhook subscriptions | ![Nuget](https://img.shields.io/nuget/dt/Deveel.Webhooks.Service?label=Deveel.Webhooks.Service&logo=nuget)| [![GitHub](https://img.shields.io/static/v1?label=Deveel.Webhooks.Service&message=Pre-Release&color=yellow&logo=github)](https://github.com/deveel/deveel.webhooks/pkgs/nuget/Deveel.Webhooks.Service) |
| **Deveel.Webhooks.MongoDb** | An implementation of the webhoom management data layer that is backed by [MongoDB](https://mongodb.com) databases | ![Nuget](https://img.shields.io/nuget/dt/Deveel.Webhooks.MongoDb?label=Deveel.Webhooks.MongoDb&logo=nuget) | [![GitHub](https://img.shields.io/static/v1?label=Deveel.Webhooks.MongoDb&message=Pre-Release&color=yellow&logo=github)](https://github.com/deveel/deveel.webhooks/pkgs/nuget/Deveel.Webhooks.MongoDb) |
| **Deveel.Webhooks.DynamicLinq** | The webhook subscription filtering engine that uses the [Dynamic LINQ](https://dynamic-linq.net/) expressions | ![Nuget](https://img.shields.io/nuget/dt/Deveel.Webhooks.DynamicLinq?label=Deveel.Webhooks.DynamicLinq&logo=nuget) | [![GitHub](https://img.shields.io/static/v1?label=Deveel.Webhooks.DynamicLinq&message=Pre-Release&color=yellow&logo=github)](https://github.com/deveel/deveel.webhooks/pkgs/nuget/Deveel.Webhooks.DynamicLinq) |
| **Deveel.Webhooks.Receiver.AspNetCore** | An implementation of the webhook receiver that is backed by [ASP.NET Core](https://dotnet.microsoft.com/apps/aspnet) | ![Nuget](https://img.shields.io/nuget/dt/Deveel.Webhooks?label=Deveel.Webhooks.Receiver.AspNetCore&logo=nuget) | [![GitHub](https://img.shields.io/static/v1?label=Deveel.Webhooks.Receiver.AspNetCore&message=Pre-Release&color=yellow&logo=github)](https://github.com/deveel/deveel.webhooks/pkgs/nuget/Deveel.Webhooks.Receiver.AspNetCore) |

You can obtain the stable versions of these libraries from the [NuGet Official](https://nuget.org) channel.

For the _nighly builds_ and previews you can restore from the [Deveel Package Manager](https://github.com/orgs/deveel/packages).
To get the latest pre-release versions of the packages you can restore from the [Deveel Package Manager](https://github.com/orgs/deveel/packages).

## Adding the Webhook Service

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<VersionPrefix>1.1.6</VersionPrefix>
<VersionPrefix>1.1.7</VersionPrefix>
<RootNamespace>Deveel</RootNamespace>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Authors>antonello</Authors>
<Company>Deveel</Company>
<Company>Deveel AS</Company>
<Description>An engine of the Deveel Webhooks framework that uses the Dynamic LINQ expressions to evaluate filters</Description>
<Copyright>Copyright (C) 2021-2022 Deveel</Copyright>
<Copyright>Copyright (C) 2021-2023 Deveel AS</Copyright>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageIcon>deveel-logo.png</PackageIcon>
<RepositoryUrl>https://github.com/deveel/deveel.webhooks</RepositoryUrl>
Expand All @@ -22,7 +22,7 @@
<Compile Remove="Webhooks\WebhookServiceBuilderExtensions.cs" />
</ItemGroup>

<ItemGroup>
<ItemGroup>
<None Include="..\..\deveel-logo.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
Expand All @@ -33,7 +33,11 @@
</None>
</ItemGroup>

<ItemGroup>
<ItemGroup>
<None Include="..\..\apl-2.licenseheader" Link="apl-2.licenseheader" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.2" />
</ItemGroup>

Expand Down
Loading

0 comments on commit 771e80e

Please sign in to comment.