Skip to content

[Group] Use modifier in group to add middleware not working #804

Open
@zhenzou

Description

@zhenzou

Use modifier to add middleware in group not working.

Reproduce code

package main

import (
	"context"
	"net/http"
	"net/http/httptest"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humagin"
	"github.com/gin-gonic/gin"
)

type TestOutput struct {
	Body struct {
		ID string `json:"id"`
	}
}

type TestInput struct {
	ID string `path:"id"`
}

func main() {
	engine := gin.New()
	api := humagin.New(engine, huma.DefaultConfig("My API", "1.0.0"))

	v1 := huma.NewGroup(api, "/v1")

        // For some reason, we can not use v1.UseMiddleware
	v1.UseSimpleModifier(func(o *huma.Operation) {
		o.Middlewares = append(o.Middlewares, func(ctx huma.Context, next func(huma.Context)) {
			header := ctx.Header("X-Test")
			if header == "" {
				ctx.SetStatus(http.StatusUnauthorized)
				return
			}
			next(ctx)
		})
	})

	huma.Get(v1, "/test/{id}", func(ctx context.Context, input *TestInput) (*TestOutput, error) {
		return &TestOutput{
			Body: struct {
				ID string `json:"id"`
			}{
				ID: input.ID,
			},
		}, nil
	})

	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodGet, "/v1/test/123", nil)
	engine.ServeHTTP(w, req)

	println(w.Code)
}

We do not pass the required test header, so Expected: 401 But Actual: 200.

We find the adapter do not respect the Operation's middlewares.

func (a *ginAdapter) Handle(op *huma.Operation, handler func(huma.Context)) {
	// Convert {param} to :param
	path := op.Path
	path = strings.ReplaceAll(path, "{", ":")
	path = strings.ReplaceAll(path, "}", "")
	a.router.Handle(op.Method, path, func(c *gin.Context) {
		ctx := &ginCtx{op: op, orig: c}
		handler(ctx)
	})
}

And we change the adapter to the code below, the middleware worked.

func (a *ginAdapter) Handle(op *huma.Operation, handler func(huma.Context)) {
	// Convert {param} to :param
	path := op.Path
	path = strings.ReplaceAll(path, "{", ":")
	path = strings.ReplaceAll(path, "}", "")
	a.router.Handle(op.Method, path, func(c *gin.Context) {
		ctx := &ginCtx{op: op, orig: c}
		op.Middlewares.Handler(handler)(ctx)
	})
}

However, we're uncertain if this behavior is intentional. Implementing middleware via modifiers may lead to unintended side effects and should be avoided unless explicitly required by the design.

Please help, thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions