refactor: eliminate middleware transformer functions, implement middleware directly on structs#136
refactor: eliminate middleware transformer functions, implement middleware directly on structs#136gaarutyunov wants to merge 4 commits into
Conversation
…eware directly on structs Removes the standalone `inbound.ValidatorMiddleware` and `outbound.Middleware` transformer functions that wrapped concrete types into HTTP middleware. Instead, introduces embeddable base structs (`ValidatorBase` in the inbound package and `ProviderBase` in the outbound package) that provide a `Middleware()` method directly on each concrete validator/provider type. Each concrete type embeds the appropriate base and wires the self-reference in its constructor via `NewValidatorBase(v)` / `NewProviderBase(p)`. This follows the same pattern already used by `transform.CompiledTransforms.RequestMiddleware()`, where the middleware behaviour lives directly on the struct rather than requiring an external adapter call. Co-authored-by: German Arutyunov <gaarutyunov@users.noreply.github.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 59 minutes and 8 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (23)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@claude you still created a wrapper. The problem is that middleware is a function. Change middleware to be an interface and implement it on the structs. You will have to change all the code related to middleware. |
|
Claude finished @gaarutyunov's task in 19m 49s —— View job Refactoring Middleware to Interface
What changed:
type Middleware interface {
Wrap(next http.Handler) http.Handler
}
type MiddlewareFunc func(http.Handler) http.Handler
func (f MiddlewareFunc) Wrap(next http.Handler) http.Handler { return f(next) }
Shared middleware logic lives as exported package functions (
|
- Define inbound.Middleware and outbound.Middleware as interfaces with Wrap(next http.Handler) http.Handler - Add MiddlewareFunc adapters (mirrors http.HandlerFunc / http.Handler) - Remove ValidatorBase and ProviderBase embedding from all concrete types - Export ServeValidated and ExtractBearerToken from inbound package, ServeWithProvider from outbound package, for use by sub-packages - Each concrete type (jwt.Validator, apikey.Validator, introspection.Validator, bearer.Provider, etc.) now directly implements Wrap on the struct - Store apiKeyHeader in apikey.Validator at construction time (no longer passed as an argument to Middleware()) - DispatchMiddleware now takes/returns inbound.Middleware interface - proxy.go uses MiddlewareFunc to adapt registry's func(http.Handler) http.Handler Co-authored-by: German Arutyunov <gaarutyunov@users.noreply.github.com>
|
@claude no wraps, check how caddy does it. It uses ServeHTTP standard handler interface. Use same approach, no functions, no wraps. Fix it everywhere!!!! |
|
Claude finished @gaarutyunov's task in 23m 14s —— View job Refactoring Middleware to
|
…-style) Remove the Middleware interface (Wrap method) from inbound and outbound packages. Remove MiddlewareFunc adapters. Each concrete validator/provider struct now has a Next http.Handler field and implements ServeHTTP directly, following the standard net/http handler pattern used by Caddy. DispatchMiddleware is replaced by NewDispatchHandler which returns http.Handler. RequestMiddleware() is replaced by transform.Handler struct. ClientIPMiddleware wraps ClientIPHandler struct. buildAuth returns raw factory functions; proxy.go wires dispatch per endpoint without a Middleware interface layer. Co-authored-by: German Arutyunov <gaarutyunov@users.noreply.github.com>
|
@claude Refactor the registries to to use the interface and remove all those wrapping functions. You now have functions inside servehttp. And the constructors are returning functions. Get rid of it. Just code inside the servehttp. |
|
Claude finished @gaarutyunov's task in 22m 31s —— View job Refactoring Registries — Removing Wrapper FunctionsWhat changed:
Summary of changes:
type Builder interface {
Build(next http.Handler) http.Handler
}
type Factory func(ctx context.Context, cfg any) (Builder, error)Each // Before:
pkgmiddleware.Register("inbound/jwt", func(ctx context.Context, cfg any) (func(http.Handler) http.Handler, error) {
v, err := NewValidator(ctx, ic.JWT)
return func(next http.Handler) http.Handler { // ← inner function
return &Validator{verifier: v.verifier, Next: next}
}, nil
})
// After:
pkgmiddleware.Register("inbound/jwt", func(ctx context.Context, cfg any) (pkgmiddleware.Builder, error) {
ic, ok := cfg.(*config.InboundAuthConfig)
// ...
return NewValidator(ctx, ic.JWT) // returns *Validator directly
})Each struct implements func (v *Validator) Build(next http.Handler) http.Handler {
return &Validator{verifier: v.verifier, Next: next}
}
func (v *Validator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
token := inbound.ExtractBearerToken(r)
if token == "" {
inbound.WriteUnauthorized(w, r, "missing_token")
return
}
info, err := v.ValidateToken(r.Context(), token)
if err != nil { ... }
v.Next.ServeHTTP(w, r.WithContext(inbound.WithTokenInfo(r.Context(), info)))
}Callers use // Before: h = outboundMW(executor)
// After: h = outboundBuilder.Build(executor) |
…TTP logic - Change middleware.Factory return type from func(http.Handler) http.Handler to Builder interface with Build(next http.Handler) http.Handler method - Each struct implements Build directly — no anonymous inner closures in init() - Inline ServeValidated/ServeWithProvider logic into each struct's ServeHTTP - Export inbound.WriteUnauthorized, WriteDenied, WithTokenInfo helpers - Export outbound.WithHeaders, WithAuthResult, AuthErrResult helpers - Update builder.go, refresh.go, proxy.go to use .Build(next) instead of fn(next) Co-authored-by: German Arutyunov <gaarutyunov@users.noreply.github.com>
Removes the standalone
inbound.ValidatorMiddlewareandoutbound.Middlewaretransformer functions. Introduces embeddable base structs (ValidatorBase,ProviderBase) that provideMiddleware()methods directly on each concrete type, following the same pattern astransform.CompiledTransforms.RequestMiddleware().Closes #133
Generated with Claude Code