fiber/hooks.go
M. Efe Çetin bd20e90e6b
feature: add initial support for hooks (#1777)
* Add initial support for hooks.

* release ctx, mutex.

* Add unit tests.

* add comment lines.

* update

* update

* remove unnecessary code.

* fix race condition.

* fix gosec.

* skip error handling for onshutdown and onresponse.

* update

* separate hooks from app.go

* make hooks field private, hook struct public and Hooks() func.

* remove onreq and onres because of they can be done by middlewares.

* OnGroupName method.

* Update hooks.go

Co-authored-by: hi019 <65871571+hi019@users.noreply.github.com>

* handle errors for name and groupname

* fix tests.

* Update app.go

* use struct fields instead of map

* add multi-handler.

* add onGroup, make prefix field public on Group struct.

* Update hooks.go

* add newhooks method.

*  feature: add initial support for hooks

* remove ctx from hooks.

Co-authored-by: hi019 <65871571+hi019@users.noreply.github.com>
Co-authored-by: wernerr <rene@gofiber.io>
2022-03-10 08:35:15 +01:00

142 lines
3.4 KiB
Go

package fiber
// Handlers define a function to create hooks for Fiber.
type OnRouteHandler = func(Route) error
type OnNameHandler = OnRouteHandler
type OnGroupHandler = func(Group) error
type OnGroupNameHandler = OnGroupHandler
type OnListenHandler = func() error
type OnShutdownHandler = OnListenHandler
type hooks struct {
// Embed app
app *App
// Hooks
onRoute []OnRouteHandler
onName []OnNameHandler
onGroup []OnGroupHandler
onGroupName []OnGroupNameHandler
onListen []OnListenHandler
onShutdown []OnShutdownHandler
}
func newHooks(app *App) *hooks {
return &hooks{
app: app,
onRoute: make([]OnRouteHandler, 0),
onGroup: make([]OnGroupHandler, 0),
onGroupName: make([]OnGroupNameHandler, 0),
onName: make([]OnNameHandler, 0),
onListen: make([]OnListenHandler, 0),
onShutdown: make([]OnShutdownHandler, 0),
}
}
// OnRoute is a hook to execute user functions on each route registeration.
// Also you can get route properties by route parameter.
func (h *hooks) OnRoute(handler ...OnRouteHandler) {
h.app.mutex.Lock()
h.onRoute = append(h.onRoute, handler...)
h.app.mutex.Unlock()
}
// OnName is a hook to execute user functions on each route naming.
// Also you can get route properties by route parameter.
//
// WARN: OnName only works with naming routes, not groups.
func (h *hooks) OnName(handler ...OnNameHandler) {
h.app.mutex.Lock()
h.onName = append(h.onName, handler...)
h.app.mutex.Unlock()
}
// OnGroup is a hook to execute user functions on each group registeration.
// Also you can get group properties by group parameter.
func (h *hooks) OnGroup(handler ...OnGroupHandler) {
h.app.mutex.Lock()
h.onGroup = append(h.onGroup, handler...)
h.app.mutex.Unlock()
}
// OnGroupName is a hook to execute user functions on each group naming.
// Also you can get group properties by group parameter.
//
// WARN: OnGroupName only works with naming groups, not routes.
func (h *hooks) OnGroupName(handler ...OnGroupNameHandler) {
h.app.mutex.Lock()
h.onGroupName = append(h.onGroupName, handler...)
h.app.mutex.Unlock()
}
// OnListen is a hook to execute user functions on Listen, ListenTLS, Listener.
func (h *hooks) OnListen(handler ...OnListenHandler) {
h.app.mutex.Lock()
h.onListen = append(h.onListen, handler...)
h.app.mutex.Unlock()
}
// OnShutdown is a hook to execute user functions after Shutdown.
func (h *hooks) OnShutdown(handler ...OnShutdownHandler) {
h.app.mutex.Lock()
h.onShutdown = append(h.onShutdown, handler...)
h.app.mutex.Unlock()
}
func (h *hooks) executeOnRouteHooks(route Route) error {
for _, v := range h.onRoute {
if err := v(route); err != nil {
return err
}
}
return nil
}
func (h *hooks) executeOnNameHooks(route Route) error {
for _, v := range h.onName {
if err := v(route); err != nil {
return err
}
}
return nil
}
func (h *hooks) executeOnGroupHooks(group Group) error {
for _, v := range h.onGroup {
if err := v(group); err != nil {
return err
}
}
return nil
}
func (h *hooks) executeOnGroupNameHooks(group Group) error {
for _, v := range h.onGroupName {
if err := v(group); err != nil {
return err
}
}
return nil
}
func (h *hooks) executeOnListenHooks() error {
for _, v := range h.onListen {
if err := v(); err != nil {
return err
}
}
return nil
}
func (h *hooks) executeOnShutdownHooks() {
for _, v := range h.onShutdown {
_ = v()
}
}