Similar to familiar middlewares that are used in request handling pipeline, the library introduces the "Registration Middleware" concept.
type RegMiddleware func(op huma.Operation, next func(huma.Operation))
Registration Middlewares are stored in each APIGen
instance and are chained and called upon registration of each
operation with the APIGen
instance.
They are used only during the registration process and don't slow down request handling.
This powerful concept allows you to control the registration process flexibly:
- Modify operation properties before registration
- Prevent registration of some operations
- Register operation multiple times with different properties
- Produce side effects during registration (e.g. maintain own permission registry)
To create a new APIGen
instance with given Registration Middlewares attached:
myRegMiddleware := func(op huma.Operation, next func(huma.Operation)) {
// do something with the operation
next(op)
}
myApi := api.AddRegMiddleware(myRegMiddleware)
For most of the cases when you need to modify an operation and produce some side effects, you can use Operation Handlers (see library provided ones) and add them as Registration Middlewares.
Actually, when you do the following:
myApi := api.AddOpHandler(op_handlers.AddTags("tag1", "tag2"))
It's the same as:
myRegMiddleware := func(op huma.Operation, next func(huma.Operation)) {
op_handlers.AddTags("tag1", "tag2")(&op)
next(op)
}
If you want to see the changes made by all registration middlewares
in the chain (in derived APIGen
instances) before an operation will be actually registered in Huma, here is the way:
bubblingRegMiddleware := func(op huma.Operation, next func(huma.Operation)) {
// do something with the operation
next(op)
}
api = api.AddBubblingRegMiddleware(bubblingRegMiddleware)
derived = api.AddOpHandler(op_handlers.AddTags("tag1"))
In this example bubblingRegMiddleware
will receive an operation registered with derived
back being able
to observe added tags.