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.
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:
/* ============================ User Group ============================ */
apiRouter.Group("/users", func(userRouter *core.Group) {
// Allow admin permission to access `/users/*` API
userRouter.Use(middleware.CheckRolesMiddleware(
[]types.Role{types.RoleAdmin},
prefixAPI+"/users/profile",
))
userRouter.GET("", user.NewListUsersApi())
userRouter.POST("", user.NewCreateUserApi())
userRouter.PUT("/{id}/status", r.Apply(middleware.PreventUpdateYourSelf)(user.NewUpdateUserStatusApi()))
userRouter.PUT("/{id}", r.Apply(middleware.PreventUpdateYourSelf)(user.NewUpdateUserApi()))
userRouter.DELETE("/{id}", r.Apply(middleware.PreventUpdateYourSelf)(user.NewDeleteUserApi()))
userRouter.GET("/{id}", user.NewGetUserByIdApi())
userRouter.GET("/profile", user.NewGetUserProfileApi())
})
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
Apply()
to apply only to a specific Controller (Handler).
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 log_middleware.go
in folder app/http/middleware/
package middleware
import (
"app/app/domain/models"
"app/app/http/response"
"app/app/modules/jwt"
"github.com/gflydev/core"
"strconv"
)
// LogRequest is a middleware that logs every request.
func LogRequest(c *core.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 api_routes.go
// WebRoutes func for describe a group of Web page routes.
func WebRoutes(f gfly.IFly) {
f.Use(middleware.LogRequest)
// 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 log_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.