Response Middleware
The maniflex/middleware/response package shapes the outgoing response —
headers, body transforms, redactions, and observability hooks — on the
Response step.
Cross-cutting headers
CORSHeaders
Adds CORS headers to every response. Reasonable defaults; pass options to restrict origins, methods, or credentials.
import "github.com/xaleel/maniflex/middleware/response"
server.Pipeline.Response.Register(response.CORSHeaders())
AddHeader
Sets one static header on every response:
server.Pipeline.Response.Register(
response.AddHeader("Strict-Transport-Security", "max-age=63072000"),
)
Caching
Cache
Sets Cache-Control: public, max-age=N on successful reads. Register at
maniflex.After so the framework’s own headers do not override yours:
server.Pipeline.Response.Register(
response.Cache(300), // 5 minutes
maniflex.ForOperation(maniflex.OpRead, maniflex.OpList),
maniflex.AtPosition(maniflex.After),
)
Body transforms
TransformField
Rewrites a single field value before serialisation. Common use: rebasing a stored relative path onto a CDN host.
server.Pipeline.Response.Register(
response.TransformField("avatar_url", func(v any) any {
return cdnBase + v.(string)
}),
)
RedactField
Hides a field from the response conditionally. The predicate decides per
request, often based on ctx.Auth:
server.Pipeline.Response.Register(
response.RedactField("phone", func(ctx *maniflex.ServerContext) bool {
return !ctx.HasRole("support")
}),
)
RedactField is the right tool for view-time access control on individual
columns. For all-or-nothing exclusion across an entire model, the hidden or
writeonly field tag is simpler.
Envelope
Replaces the default {"data": ...} envelope with one of your own:
server.Pipeline.Response.Register(
response.Envelope(func(ctx *maniflex.ServerContext, data any, meta *maniflex.ResponseMeta) any {
return map[string]any{
"result": data,
"paging": meta,
"trace_id": ctx.TraceID,
}
}),
)
Useful when integrating with a frontend or API gateway that expects a different shape. Error responses are unaffected; only success responses are re-enveloped.
Observability
Logging
Writes a structured access log line per request at maniflex.After:
server.Pipeline.Response.Register(
response.Logging(slog.Default()),
maniflex.AtPosition(maniflex.After),
)
The line carries request ID, trace ID, method, path, status, duration, and the authenticated user when set.
Metrics
Records per-request metrics — count, latency, status class — into a configured collector:
server.Pipeline.Response.Register(
response.Metrics(myCollector),
maniflex.AtPosition(maniflex.After),
)
A reference Prometheus collector is provided; any sink with the same interface works.