-
-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Value attached to request context in chi middleware is not available in context in huma operation #197
Comments
In Huma, the operation handler dependencies need to be a bit more explicit, so you don't get access to the context vars implicitly. You can do this using a resolver and including that in your input struct via composition for the operation handler, then explicitly accessing it via e.g. type AuthHeader struct {
User string
}
func (a *AuthHeader) Resolve(ctx huma.Context) []error {
if v := ctx.Context().Value("user"); v != nil {
a.User = v.(string)
}
return nil
}
func main() {
router := chi.NewMux()
router.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r = r.WithContext(context.WithValue(r.Context(), "user", "foo"))
next.ServeHTTP(w, r)
})
})
// Register GET /greeting/{name}
huma.Register(api, huma.Operation{
OperationID: "get-greeting",
Summary: "Get a greeting",
Method: http.MethodGet,
Path: "/greeting/{name}",
}, func(ctx context.Context, input *struct {
AuthHeader
GreetingInput
}) (*GreetingOutput, error) {
fmt.Println("User is", input.User)
resp := &GreetingOutput{}
resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
return resp, nil
})
} While it's not as "nice" as just pulling things from the request context, this was done on purpose to make all the inputs/outputs of an operation explicitly defined and limit the magic that can confuse people and lead to mistakes. |
Great answer! Follow up question: how can I access a dependency, e.g. database connection, in the resolver function? I could potentially add the dependency to the request context in middleware call before but this seems overly complex. |
You can't directly access dependencies that aren't in scope in a resolver. It's recommended you do this in the handler function or using some middleware that can be initialized with the dependency before use.
Right, you can't update the context from a resolver, but you can set fields on the resolved struct for use by the operation handler. The |
I am currently porting over a code from a pure chi router to huma + chi. I have a middleware that checks the Bearer token in the request header and fetches the user object from the db and then attaches it to the request context to make it available in all downstream functions. While porting the code over I ran into an issue. When I attach a value to the context of a request in a chi middleware, the value is not available in the context of the huma Operation.
My mental framework is as following:
Request -> chi middleware -> attaches value to Request context -> Request context is copied and made available in each huma Operation
That mental framework is not accurate. I'd like to understand where it breaks and how to best fix my issue of making a user object available within a huma Operation.
Code example below:
The text was updated successfully, but these errors were encountered: