Middleware Usage
On this page
Use this guide when you need to implement request policy, security enforcement, or observability in your Nalix application.
Core Concepts
In Nalix, middleware is organized into the MiddlewarePipeline. This pipeline operates on deserialized packets (IPacketContext<TPacket>), allowing you to make decisions based on both the packet data and the resolved handler metadata. An inbound frame is deserialized into a packet, passed through the MiddlewarePipeline, then handed to your handler.
When to use Middleware
Use middleware when you need to enforce logic that applies to many different packet types or handlers.
Typical cases:
- Permission checks: Block requests based on connection status or auth level.
- Timeout rules: Cancel handler execution if it takes too long.
- Rate limiting: Throttling requests to prevent spam.
- Concurrency limits: Preventing too many simultaneous executions of heavy handlers.
- Auditing and tracing: Logging request details for debugging or compliance.
A safe build order
For most projects, middleware usually grows cleanly in this order:
- Start with one simple middleware (e.g., logging).
- Add metadata-driven policy (using Attributes) only when repeated rules appear across different handlers.
- Keep middleware focused—prefer multiple specific middlewares over one massive “god” middleware.
Example: Registering Middleware
PacketDispatchChannel dispatch = new(options =>
{
options.WithMiddleware(new PermissionMiddleware())
.WithMiddleware(new SampleAuditMiddleware<IPacket>())
.WithHandler(() => new SamplePingHandlers());
});
Low-Level Processing (Non-Middleware)
If you need to perform actions on raw bytes (like custom decryption or transformation) before they become packets, this logic is handled by the Protocol and the FramePipeline in the transport layer, rather than the MiddlewarePipeline.
Common mistakes
- Putting too many unrelated policies in one middleware.
- Adding custom metadata before proving you need it.
- Forgetting that middleware execution order is sorted by
[MiddlewareOrder(int)]ascending (default0, preserving registration order on ties), and reversed on outbound whenExecuteOnOutboundis enabled.
Good default patterns
For public traffic, a good starting setup is:
ConnectionGuardat the transport layer for early admission control.PermissionMiddlewareto ensure only authorized clients reach handlers.RateLimitMiddlewareto protect your resources.