Skip to main content

Plugins

QvaSoft Gateway supports custom delegating handlers that extend request/response processing. Plugins are loaded dynamically from DLL files at startup.

How It Works

  1. Build a .NET class library that extends DelegatingHandler
  2. Implement the required Name and IsGlobal properties
  3. Drop the DLL into the Plugins/ folder
  4. 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 Name property (string) -- the display name shown in the admin panel
  • Expose an IsGlobal property (bool) -- true to apply to all routes, false for 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

PropertyTypeDescription
NamestringDisplay name shown in the admin panel dropdown
IsGlobalbooltrue = applied to all routes automatically, false = assigned per route
warning

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

HandlerDescription
TracingSends request details to a configured tracing endpoint