Plugins
QvaSoft Gateway supports custom delegating handlers that extend request/response processing. Plugins are loaded dynamically from DLL files at startup.
How It Works
- Build a .NET class library that extends
DelegatingHandler - Implement the required
NameandIsGlobalproperties - Drop the DLL into the
Plugins/folder - The gateway discovers and loads it automatically on startup
Creating a Plugin
Create a new .NET class library project:
dotnet new classlib -n MyPlugin
Your plugin class must:
- Extend
DelegatingHandler - Expose a
Nameproperty (string) -- the display name shown in the admin panel - Expose an
IsGlobalproperty (bool) --trueto apply to all routes,falsefor per-route use
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace MyPlugin
{
public class LoggingHandler : DelegatingHandler
{
public string Name => "Request Logger";
public bool IsGlobal => false;
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// Pre-processing
Console.WriteLine($"Request: {request.Method} {request.RequestUri}");
var response = await base.SendAsync(request, cancellationToken);
// Post-processing
Console.WriteLine($"Response: {response.StatusCode}");
return response;
}
}
}
Plugin Contract
| Property | Type | Description |
|---|---|---|
Name | string | Display name shown in the admin panel dropdown |
IsGlobal | bool | true = applied to all routes automatically, false = assigned per route |
Both Name and IsGlobal properties are required. Classes that don't implement them will be ignored by the plugin loader.
Building and Installing
Build and copy the DLL to the Plugins/ folder:
dotnet build -c Release
cp bin/Release/net10.0/MyPlugin.dll /path/to/ApiGateway/Plugins/
Restart the gateway to load the new plugin.
Using a Plugin in Routes
For non-global plugins (IsGlobal = false), reference the handler class name in the DelegatingHandlers array of a route:
{
"UpstreamPathTemplate": "/api/orders/{everything}",
"DownstreamPathTemplate": "/api/{everything}",
"DelegatingHandlers": ["LoggingHandler"]
}
Multiple handlers are executed in order:
{
"DelegatingHandlers": ["LoggingHandler", "AuthEnrichmentHandler"]
}
Global plugins (IsGlobal = true) are applied to all routes automatically and don't need to be listed in DelegatingHandlers.
Plugin Discovery
The admin panel automatically discovers all loaded plugins and shows them in the delegating handlers dropdown when editing routes.
Built-in Handlers
| Handler | Description |
|---|---|
Tracing | Sends request details to a configured tracing endpoint |