Last active
October 9, 2023 03:40
-
-
Save iflamed/8a50f22c961c9cd2e027955d4a2494a0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Package http | |
package http | |
import ( | |
"github.com/gin-gonic/gin" | |
"net/http" | |
) | |
type Context struct { | |
*gin.Context | |
} | |
// Ok implement your context method like below | |
func (c *Context) Ok(body string) { | |
c.String(http.StatusOK, body) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Handler interface { | |
GetHandler(action string) HandlerFunc | |
Clone() Handler | |
} | |
type BasicHandler struct { | |
Handlers map[string]HandlerFunc | |
} | |
func (b *BasicHandler) SetHandler(action string, handlerFunc HandlerFunc) { | |
if b.Handlers == nil { | |
b.Handlers = make(map[string]HandlerFunc) | |
} | |
b.Handlers[action] = handlerFunc | |
} | |
func (b *BasicHandler) GetHandler(action string) HandlerFunc { | |
return b.Handlers[action] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// register route and use custom context | |
func initRoutes(r *router) { | |
r.GET("/hello", func(c *Context) { | |
c.Ok("Hello world") | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type router struct { | |
*gin.RouterGroup | |
} | |
type Controller struct { | |
r *router | |
h Handler | |
} | |
type HandlerFunc func(c *Context) | |
func newRouter(e *gin.Engine) *router { | |
return &router{ | |
RouterGroup: &e.RouterGroup, | |
} | |
} | |
func (r *router) GET(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodGet, relativePath, handlers...) | |
return r | |
} | |
func (r *router) POST(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodPost, relativePath, handlers...) | |
return r | |
} | |
func (r *router) PUT(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodPut, relativePath, handlers...) | |
return r | |
} | |
func (r *router) PATCH(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodPatch, relativePath, handlers...) | |
return r | |
} | |
func (r *router) HEAD(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodHead, relativePath, handlers...) | |
return r | |
} | |
func (r *router) OPTIONS(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodOptions, relativePath, handlers...) | |
return r | |
} | |
func (r *router) DELETE(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodDelete, relativePath, handlers...) | |
return r | |
} | |
func (r *router) CONNECT(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodConnect, relativePath, handlers...) | |
return r | |
} | |
func (r *router) TRACE(relativePath string, handlers ...HandlerFunc) *router { | |
r.wrapRoute(http.MethodTrace, relativePath, handlers...) | |
return r | |
} | |
func (r *router) Use(handlers ...HandlerFunc) *router { | |
r.wrapRoute("use", "", handlers...) | |
return r | |
} | |
func (r *router) Group(relativePath string, handlers ...HandlerFunc) *router { | |
g := r.wrapRoute("group", relativePath, handlers...).(*gin.RouterGroup) | |
return &router{ | |
RouterGroup: g, | |
} | |
} | |
func (r *router) wrapRoute(method string, relativePath string, handlers ...HandlerFunc) gin.IRoutes { | |
hds := make([]gin.HandlerFunc, 0, len(handlers)) | |
for _, hd := range handlers { | |
hds = append(hds, wrapHandler(hd)) | |
} | |
switch method { | |
case http.MethodGet: | |
return r.RouterGroup.GET(relativePath, hds...) | |
case http.MethodPost: | |
return r.RouterGroup.POST(relativePath, hds...) | |
case http.MethodPut: | |
return r.RouterGroup.PUT(relativePath, hds...) | |
case http.MethodPatch: | |
return r.RouterGroup.PATCH(relativePath, hds...) | |
case http.MethodHead: | |
return r.RouterGroup.HEAD(relativePath, hds...) | |
case http.MethodOptions: | |
return r.RouterGroup.OPTIONS(relativePath, hds...) | |
case http.MethodDelete: | |
return r.RouterGroup.DELETE(relativePath, hds...) | |
case http.MethodConnect: | |
return r.RouterGroup.Handle(http.MethodConnect, relativePath, hds...) | |
case "use": | |
return r.RouterGroup.Use(hds...) | |
case "group": | |
return r.RouterGroup.Group(relativePath, hds...) | |
} | |
return r.RouterGroup.Handle(http.MethodTrace, relativePath, hds...) | |
} | |
func wrapHandler(hd HandlerFunc) gin.HandlerFunc { | |
return func(ctx *gin.Context) { | |
hd(&Context{ctx}) | |
} | |
} | |
func (r *router) Controller(h Handler) *Controller { | |
return &Controller{r: r, h: h} | |
} | |
func (c *Controller) GET(relativePath, action string) *Controller { | |
c.r.GET(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) POST(relativePath, action string) *Controller { | |
c.r.POST(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) PUT(relativePath, action string) *Controller { | |
c.r.PUT(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) PATCH(relativePath, action string) *Controller { | |
c.r.PATCH(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) HEAD(relativePath, action string) *Controller { | |
c.r.HEAD(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) OPTIONS(relativePath, action string) *Controller { | |
c.r.OPTIONS(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) DELETE(relativePath, action string) *Controller { | |
c.r.DELETE(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) CONNECT(relativePath, action string) *Controller { | |
c.r.CONNECT(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) TRACE(relativePath, action string) *Controller { | |
c.r.TRACE(relativePath, c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) Use(action string) *Controller { | |
c.r.wrapRoute("use", "", c.cloneHandler(action, c.h)) | |
return c | |
} | |
func (c *Controller) Group(relativePath, action string) *Controller { | |
g := c.r.wrapRoute("group", relativePath, c.cloneHandler(action, c.h)).(*gin.RouterGroup) | |
r := &router{ | |
RouterGroup: g, | |
} | |
return r.Controller(c.h) | |
} | |
func (c *Controller) Resource(relativePath string) *Controller { | |
c.GET(relativePath, http.MethodGet) | |
c.POST(relativePath, http.MethodPost) | |
c.PUT(relativePath, http.MethodPut) | |
c.PATCH(relativePath, http.MethodPatch) | |
c.DELETE(relativePath, http.MethodDelete) | |
return c | |
} | |
func (c *Controller) cloneHandler(action string, h Handler) HandlerFunc { | |
return func(c *Context) { | |
hd := h.Clone().GetHandler(action) | |
if hd != nil { | |
hd(c) | |
} else { | |
c.Error(http.StatusInternalServerError, action+" handler not implemented", gin.H{}) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// create gin instance to start server | |
func createServer() *http.Server { | |
engine := gin.Default() | |
initRoutes(newRouter(engine)) | |
return &http.Server{ | |
Addr: "127.0.0.1:8080", | |
Handler: engine, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
May be the best way to custom gin context. Create a new context based on gin.context and create a new router.