Repository navigation
Configuration Pipelines
Configure send and receive pipelines to add cross-cutting concerns like logging, validation, and transformation to your FxMap requests and responses.
Pipelines are middleware-like components that intercept and process requests and responses in the FxMap data flow. They enable you to add cross-cutting concerns without modifying your core business logic.
Process outgoing requests before they are sent to handlers or remote services. Run on the client side.
Process incoming requests before they reach handlers. Run on the server side where data is fetched.
Client
Send Pipeline
Transport
Transport
Receive Pipeline
Server Handler
Server Handler
Response
Client
Send pipelines are configured on the client side:
builder.Services.AddFxMap(cfg =>
{
cfg.AddEntitiesFromAssemblyContaining<SomeEntityAssemblyMarker>();
cfg.AddProfilesFromAssemblyContaining<SomeProfileAssemblyMarker>();
// Add send pipelines
cfg.AddSendPipelines(c =>
{
// Add a generic pipeline
c.OfType(typeof(GenericSendPipeline<>))
.OfType(typeof(LoggingSendPipeline<>));
});
});Send pipelines implement request preprocessing logic before data is sent to the server:
using FxMap.Abstractions;
using FxMap.Delegates;
using FxMap.Responses;
public sealed class LoggingSendPipeline<TKey>(ILogger logger) :
ISendPipelineBehavior<TKey> where TKey : IDistributedKey
{
public async Task<ItemsResponse<DataResponse>> HandleAsync(
RequestContext<TKey> requestContext,
SendHandlerDelegate next)
{
logger.Information("Sending request for key {Key}", typeof(TKey).Name);
var result = await next.Invoke();
return result;
}
}Receive pipelines are configured on the server side where you handle incoming requests:
builder.Services.AddFxMap(cfg =>
{
cfg.AddEntitiesFromAssemblyContaining<SomeEntityAssemblyMarker>();
cfg.AddProfilesFromAssemblyContaining<SomeProfileAssemblyMarker>();
// Add receive pipelines
cfg.AddReceivedPipelines(c =>
{
// Add a generic pipeline
c.OfType(typeof(GenericReceivedPipeline<>))
.OfType(typeof(LoggingReceivedPipeline<>));
});
});Receive pipelines process incoming requests before they reach your handlers:
using FxMap.Abstractions;
using FxMap.Delegates;
using FxMap.Responses;
public sealed class LoggingReceivedPipeline<TKey>(ILogger logger) :
IReceivedPipelineBehavior<TKey> where TKey : IDistributedKey
{
public async Task<ItemsResponse<DataResponse>> HandleAsync(
RequestContext<TKey> requestContext,
ReceivedHandlerDelegate next)
{
logger.Information("Received request for key {Key}", typeof(TKey).Name);
var result = await next.Invoke();
return result;
}
}Track request/response flows, measure performance, and identify bottlenecks.
Validate user permissions before allowing data access.
Cache responses to reduce database load and improve performance.
Validate request parameters and data integrity.
Transform or enrich data before it's processed or returned.
// Program.cs - Client Side
builder.Services.AddFxMap(cfg =>
{
cfg.AddEntitiesFromAssemblyContaining<SomeEntityAssemblyMarker>();
cfg.AddProfilesFromAssemblyContaining<SomeProfileAssemblyMarker>();
// Configure send pipelines (client side)
cfg.AddSendPipelines(c =>
{
c.OfType(typeof(LoggingSendPipeline<>));
c.OfType<PerformanceMonitoringSendPipeline>();
});
})
.AddRabbitMq(config => { ... });
// Program.cs - Server Side
builder.Services.AddFxMap(cfg =>
{
cfg.AddEntitiesFromAssemblyContaining<SomeEntityAssemblyMarker>();
cfg.AddProfilesFromAssemblyContaining<SomeProfileAssemblyMarker>();
// Configure receive pipelines (server side)
cfg.AddReceivedPipelines(c =>
{
c.OfType<AuthorizationReceivedPipeline>();
c.OfType<CachingReceivedPipeline>();
c.OfType<ValidationReceivedPipeline>();
});
})
.AddEntityFrameworkCore(options => options.AddDbContexts(typeof(AppDbContext)))
.AddRabbitMq(config => { ... });- Keep pipelines focused on a single responsibility
- Order matters - pipelines execute in the order they are registered
- Always call next() to continue the pipeline chain
- Use dependency injection for pipeline dependencies
- Handle exceptions appropriately to avoid breaking the pipeline
- Send pipelines run on the client, receive pipelines run on the server
- Pipelines are optional - FxMap works without them
- Not calling next() will short-circuit the pipeline
- Generic pipelines (TKey) allow key-specific processing
Source: https://fxmapper.net/docs/configuration/pipelines/ — the website is always the most up to date version.
Introduction
Getting Started
Configuration
- Service Registration
- Entities & Profiles
- Handlers
- Pipelines
- Strongly Typed IDs
- Error Handling
- Retry Policy
- Supervisor
- Telemetry
- Kestrel (HTTP/2)
- Analyzers
Expressions
- Overview
- Property Access
- Filters, Sorting & Paging
- Functions
- Aggregations
- Projections
- Coalesce & Ternary
- GroupBy
Data Providers
Transports
Integrations
Quality
AI Assistants
Migration
Release Notes