Skip to content

std-http-server: allow MiddlewareFunc to be emitted as a type alias #2363

@jay-babu

Description

@jay-babu

Summary

For std-http-server, MiddlewareFunc is currently generated as a named function type:

type MiddlewareFunc func(http.Handler) http.Handler

This makes the generated middleware type package-specific. In projects that split one OpenAPI spec into multiple generated packages, a shared middleware slice such as:

[]func(http.Handler) http.Handler

cannot be passed directly into each generated package's StdHTTPServerOptions.Middlewares.

Each generated package has its own distinct type, for example:

[]core.MiddlewareFunc
[]admin.MiddlewareFunc
[]public.MiddlewareFunc

That forces callers to write conversion helpers per generated package, even though the underlying middleware shape is the standard net/http middleware signature.

Proposal

Either emit MiddlewareFunc as a type alias:

type MiddlewareFunc = func(http.Handler) http.Handler

or add a generator option that allows users to choose alias generation for middleware types.

Motivation

This would make generated std-http-server middleware easier to compose in applications that:

  • generate multiple packages from one or more OpenAPI specs
  • share the same []func(http.Handler) http.Handler middleware chain across those generated servers
  • use dependency injection or shared route registration interfaces
  • want to avoid repetitive conversion helpers like:
func toMiddlewares(mws []func(http.Handler) http.Handler) []gen.MiddlewareFunc {
    out := make([]gen.MiddlewareFunc, len(mws))
    for i, mw := range mws {
        out[i] = mw
    }
    return out
}

With an alias, callers can pass the shared middleware slice directly while preserving the existing generated API shape.

Benefits

This reduces boilerplate and makes the generated std-http-server middleware API easier to use with normal Go net/http middleware.

Today, when an application has multiple generated server packages, each package gets its own distinct MiddlewareFunc type. Even though every type has the same underlying signature, Go does not allow a []func(http.Handler) http.Handler slice to be used as a []gen.MiddlewareFunc slice. It also does not allow one generated package's middleware slice to be reused as another generated package's middleware slice.

Using an alias would let applications define middleware once:

middlewares := []func(http.Handler) http.Handler{
    requestIDMiddleware,
    authMiddleware,
    loggingMiddleware,
}

and pass that same slice to every generated std-http-server package without conversion.

That matters most for larger services that split APIs into multiple generated packages but still need one consistent middleware chain for validation, auth, logging, tracing, and metrics. The alias keeps the generated API ergonomic while still documenting the expected middleware shape through the MiddlewareFunc name.

Compatibility

Changing the type to an alias may be source-compatible for most users, but it is technically observable for users relying on MiddlewareFunc as a distinct named type.

If that compatibility risk is too high, a config option would preserve current behavior by default while allowing projects that need shared middleware composition to opt in.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions