Skip to content

Latest commit

 

History

History
122 lines (97 loc) · 5.18 KB

File metadata and controls

122 lines (97 loc) · 5.18 KB

web

Tier: Foundational · Status: Full · Java original: firefly-web + firefly-spring-utils · .NET project: FireflyFramework.Web

Overview

web is the framework's HTTP-layer middleware tier — it converts errors into RFC 7807 application/problem+json responses, propagates correlation IDs, replays idempotent requests, and scrubs PII out of log lines. Composed at the outermost edge of every Firefly service via startercore.Core.Middleware().

Every middleware is a func(http.Handler) http.Handler so it composes with stdlib net/http and any third-party router.

Why a separate module?

Spring's @ControllerAdvice and ASP.NET's exception handlers cover problem-detail rendering only. The framework needs four orthogonal middlewares to behave identically across runtimes, with the same header names, response shapes, and conflict semantics — web provides them as one composable bundle.

Mental model

incoming request
      │
      ▼
┌─────────────────────────────────────────┐
│ ProblemMiddleware  (panic → 500 RFC7807)│
└─────────────────────────────────────────┘
      │
      ▼
┌─────────────────────────────────────────┐
│ CorrelationMiddleware (X-Correlation-Id) │
└─────────────────────────────────────────┘
      │
      ▼
┌─────────────────────────────────────────┐
│ IdempotencyMiddleware (replay if Key)    │
└─────────────────────────────────────────┘
      │
      ▼
   your mux

This is the chain returned by startercore.Core.Middleware().

Public surface

Problem-detail rendering

Symbol Behaviour
WriteProblem(w, *kernel.ProblemDetail) Sets application/problem+json, writes status, encodes
WriteError(w, error) Converts via kernel.AsProblem then writes
ProblemMiddleware(next) Catches panics, renders 500 with kernel.TypeInternal
ErrorHandler(fn).AsHandler() Adapter for handlers returning error

Correlation

Symbol Behaviour
CorrelationMiddleware(next) Reads / generates X-Correlation-Id, stores on ctx, echoes back

Idempotency

Symbol Behaviour
IdempotencyConfig{Store, TTL, Methods} Tunes the middleware
DefaultIdempotencyConfig() 24 h TTL, memory store, POST/PUT/PATCH
IdempotencyMiddleware(cfg)(next) Replays cached 2xx responses; returns 409 on key reuse w/ different body
MemoryIdempotencyStore Default in-process store
IdempotencyStore interface Plug your own (Redis / Postgres / etc.)

PII masking

Symbol Behaviour
MaskPII(s) string Redacts emails, IBANs, cards, E.164 phones
MaskMap(m) map Recursive redaction; sensitive keys (password, token, secret, authorization, cookie, api_key, apikey, private_key) replaced wholesale

Quick start

import (
    "net/http"
    "github.com/fireflyframework/fireflyframework-go/kernel"
    "github.com/fireflyframework/fireflyframework-go/web"
)

mux := http.NewServeMux()
mux.Handle("POST /orders", web.ErrorHandler(func(w http.ResponseWriter, r *http.Request) error {
    if r.URL.Query().Get("customer") == "" {
        return kernel.NewBadRequest("customer is required")
    }
    // … your domain logic …
    w.WriteHeader(http.StatusCreated)
    return nil
}).AsHandler())

cfg := web.DefaultIdempotencyConfig()
chain := web.ProblemMiddleware(
    web.CorrelationMiddleware(
        web.IdempotencyMiddleware(cfg)(mux),
    ),
)
http.ListenAndServe(":8080", chain)

Testing

cd web
go test ./...

Suite covers panic→500, the typed ErrorHandler, correlation id generation + echo-back, idempotency replay (replay header, body), and PII redaction across emails / IBANs / cards / phones plus map-key sensitive-name scrubbing.