Description

If there are middleware designed only to be effective for specific methods and paths, like only GET method for paths that start with /api/v1, hope there is a way to apply the middleware to the specified path and method.

How to reproduce

Currently, there are basically two ways to achieve this, the first one using Group() are a bit less fine-grained, and it may be designed for grouping basePath rather than differentiating middleware:

import "github.com/gin-gonic/gin"

func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        println("auth passed!")
        c.Next()
    }
}

func main() {
    router := gin.Default()

    group := router.Group("/needAuth")
    group.Use(AuthMiddleware())

    group.GET("/api/v1/hello", handler1)    // need auth
    group.POST("/api/v1/hello", handler2)   // need auth

    router.GET("/api/v2/hello", handler2)   // don't need auth
}

The second way is a bit more fine-grained, but will introduce more duplication if the middleware scope become larger.

import "github.com/gin-gonic/gin"

func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        println("auth passed!")
        c.Next()
    }
}

func main() {
    router := gin.Default()

    router.GET("/api/v1/hello", AuthMiddleware(), handler1)     // need auth
    router.POST("/api/v1/hello", AuthMiddleware(), handler2)    // need auth

    router.GET("/api/v2/hello", handler2)   // don't need auth
}

Expectations

Hope there is a way to apply the middleware to the specified path and method. For example, require matching GET method and start with /api/v1

A basic idea is: https://github.com/gin-gonic/gin/pull/3780, (I'm beginner to gin, not sure if that's adequate and suitable)

Environment

  • go version: 1.21.3
  • gin version (or commit ref): 44d0dd
  • operating system: (omitted)

Comment From: Acetolyne

You could potentially add the middleware to all routes using router.Use(MyMiddleware()) then in your middleware function only run it if its a route or method that you want. Something like this In your main file router := gin.Default() router.Use(MyMiddleware())

Then where you define your middleware func MyMiddleware() gin.HandlerFunc { return func(c *gin.Context) { if c.Request.Method == "GET" && c.Request.RequestURI == "/someroute" { ACTIONS HERE TO DECIDE TO PASS } else { //We dont run anything and just pass it to the next middleware or the route c.Next() } } } instead of if statements you could also create a slice and say if route in the slice or even a list of structs and check each one if you want one for each route and defining the allowed methods