- With issues:
- Use the search tool before opening a new issue.
- Please provide source code and commit sha if you found a bug.
- Review existing issues and provide feedback or react to them.
Description
I want to use the prefix tree of Gin now. I hope to register a DINGEVENT method and build a prefix tree for this method at the same time. This step is no problem, and the following code can be used:
type MyRouterGroup struct {
RouterGroup *gin.RouterGroup
}
func (group *MyRouterGroup) DingEvent(event_url string, handlerFunc gin.HandlerFunc) {
group.RouterGroup.Handle("DINGEVENT", event_url, handlerFunc)
}
However, I have no way to enter this routing tree (unless I modify the Gin source code), because only when an HTTP request is sent, will it be matched in the routing tree.
Is there a custom method that allows me to match the routing tree like processing HTTP requests?
Environment
- go version: 1.21
- gin version (or commit ref): 1.8
- operating system: Mac
Comment From: ljluestc
package main
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
type MyRouterGroup struct {
RouterGroup *gin.RouterGroup
routes map[string]gin.HandlerFunc // Custom routing tree for DINGEVENT
}
// NewMyRouterGroup creates a new MyRouterGroup instance
func NewMyRouterGroup(router *gin.Engine, prefix string) *MyRouterGroup {
return &MyRouterGroup{
RouterGroup: router.Group(prefix),
routes: make(map[string]gin.HandlerFunc),
}
}
// DingEvent registers a new DINGEVENT route
func (group *MyRouterGroup) DingEvent(eventURL string, handlerFunc gin.HandlerFunc) {
// Add the route to the custom routing tree
group.routes[eventURL] = handlerFunc
// Optionally: Register with Gin for debugging or future use
group.RouterGroup.Handle("DINGEVENT", eventURL, handlerFunc)
}
// MatchDingEvent allows manual matching of a DINGEVENT route
func (group *MyRouterGroup) MatchDingEvent(eventURL string) (gin.HandlerFunc, bool) {
// Match the route in the custom routing tree
handler, exists := group.routes[eventURL]
return handler, exists
}
func main() {
router := gin.Default()
// Create a custom router group
myGroup := NewMyRouterGroup(router, "/api")
// Register a DINGEVENT route
myGroup.DingEvent("/ding", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Ding Event Triggered"})
})
// Add an HTTP endpoint to trigger a DINGEVENT manually
router.GET("/trigger-ding/:path", func(c *gin.Context) {
// Extract the event path
eventPath := fmt.Sprintf("/%s", strings.TrimPrefix(c.Param("path"), "/"))
// Match the DINGEVENT route
if handler, exists := myGroup.MatchDingEvent(eventPath); exists {
// Create a new Gin context to invoke the handler
context := &gin.Context{
Writer: c.Writer,
Request: c.Request,
}
handler(context) // Call the matched handler
} else {
c.JSON(http.StatusNotFound, gin.H{"error": "Ding Event Not Found"})
}
})
// Start the server
router.Run(":8080")
}