Middleware #
Middleware provides a convenient mechanism for inspecting and filtering HTTP requests entering your application. For example, gFly includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to your application’s login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
Additional middleware can be written to perform a variety of tasks besides authentication. For example, a logging middleware might log all incoming requests to your application. There are several middleware included in the gFly framework. All of these middleware are located in the app/http/middleware directory.
Middleware will affect child router groups and is not limited to levels.
Register Middleware #
There are two ways to add middleware to the router. Suppose there is a middleware registration in API router app/http/routes/api_routes.go
as follows:
func ApiRoutes(f gfly.IFly) {
// Write log all request URL
f.Use(middleware.RequestMiddlewareFunc)
f.Group("/api/v1", func(apiRouter *gfly.Group) {
apiRouter.Group("/checking", func(groupChecking *gfly.Group) {
// Check Authentication and Authorization
groupChecking.Use(middleware.ExtraMiddlewareFunc,
middleware.AuthMiddlewareFunc)
groupChecking.GET("/unauthorized", api.NewDefaultApi())
groupChecking.GET("/forbidden", api.NewDefaultApi())
groupChecking.POST("/one", f.Middleware(middleware.RuleMiddlewareFunc)(api.NewDefaultApi()))
})
})
}
You can see that you can use 2 ways below to use Middleware:
- Use
Use()
to apply routers at the same or nested level. - Use
Middleware()
to apply only to a specific Controller (Handler).
You can see there are 4 middleware functions: RequestMiddlewareFunc
, ExtraMiddlewareFunc
, AuthMiddlewareFunc
and RuleMiddlewareFunc
Therefore, depending on the request, the amount of middleware that will be required to handle will be different:
- All requests
/*
will be affected by at least a middlewareRequestMiddlewareFunc
. - Request URL
/api/v1/checking/unauthorized
and/api/v1/checking/forbidden
will be affected by 3 middlewaresRequestMiddlewareFunc
,ExtraMiddlewareFunc
, andAuthMiddlewareFunc
. - Only request URL
/api/v1/checking/one
will be affected by 4 middlewareRequestMiddlewareFunc
,ExtraMiddlewareFunc
,AuthMiddlewareFunc
andRuleMiddlewareFunc
.
Defining Middleware #
Middleware function must be a type of MiddlewareHandler
type MiddlewareHandler func(ctx *Ctx) error
Let review middleware RequestMiddlewareFunc
. This middleware just print out URL requests
Create file request_middleware.go
in folder app/http/middleware/
package middleware
import (
"app/core/gfly"
"app/core/log"
)
func RequestMiddlewareFunc(c *gfly.Ctx) error {
log.Infof("Request %s", c.OriginalURL())
return nil
}
Declare middleware
into app/http/routes/web_routes.go
or app/http/routes/api_routes.go
Below example add to web_routes.go
// WebRoutes func for describe a group of Web page routes.
func WebRoutes(f gfly.IFly) {
// Write log all request URL
f.Use(middleware.RequestMiddlewareFunc)
// Web Routers
...
}
Browse http://localhost:7789/hello
and check log file storage/logs/logs.log
and see more log content
2024/01/31 14:14:27.996562 request_middleware.go:9: [INFO] Request /hello
Simple task!. Therefore, this middleware does not need to check or block the processing flow of requests to the controller. So it will return nil. However, suppose you have middleware where necessity limits certain requests. Then you need to return error (any type) then the system will understand that the request is interrupted.