danielgtaylor / danielgtaylor/huma

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

Open
#804 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
4.4k
Forks
285
Avg merge
40m
Merged PRs (30d)
1

Description

Use modifier to add middleware in group not working.

Reproduce code

```go
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.

```go
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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.