Header-basierte Versionskontrolle auf Golang ist eine effiziente Möglichkeit, Codeversionen während der Entwicklung zu verwalten. Durch das Hinzufügen von Versionsinformationen am Anfang von Codedateien können Entwickler Codeänderungen und Versionsverlauf einfach verfolgen. Diese Versionskontrollmethode ist nicht nur einfach zu verwenden, sondern auch für Projekte jeder Größe geeignet. Der PHP-Editor Xigua wird in diesem Artikel ausführlich die Verwendung und Vorsichtsmaßnahmen der Header-basierten Versionskontrolle auf Golang vorstellen, um Entwicklern dabei zu helfen, Code besser zu verwalten und zu warten. Egal, ob Sie Anfänger oder erfahrener Entwickler sind, dieser Artikel bietet Ihnen wertvolle Referenzen und Anleitungen. Lassen Sie uns gemeinsam diese interessante und praktische Versionskontrolltechnologie erkunden!
Ich möchte Gin verwenden, um unterwegs eine Header-basierte Versionskontrolle zu implementieren. Ich denke darüber nach, eine Middleware-Funktion zu verwenden, um dies auf dem Router zu tun.
Der Client ruft dieselbe API-URL auf und die Version befindet sich in einem benutzerdefinierten HTTP-Header wie diesem:
Version 1 aufrufen Holen Sie sich /users/12345678 Akzeptierte Version: v1
Version 2 aufrufen: Holen Sie sich /users/12345678 Akzeptierte Version: v2
So kann der Router den Header erkennen und die spezifische Version aufrufen. Dinge wie diese:
router := gin.Default() v1 := router.Group("/v1") v1.Use(VersionMiddleware()) v1.GET("/user/:id", func(c *gin.Context) { c.String(http.StatusOK, "This is the v1 API") }) v2 := router.Group("/v2") v2.Use(VersionMiddleware()) v2.GET("/user/:id", func(c *gin.Context) { c.String(http.StatusOK, "This is the v2 API") }) func VersionMiddleware() gin.HandlerFunc { return func(c *gin.Context) { version := c.Request.Header.Get(configuration.GetConfigValue("VersionHeader")) // Construct the new URL path based on the version number path := fmt.Sprintf("/%s%s", version, c.Request.URL.Path) // Modify the request URL path to point to the new version-specific endpoint c.Request.URL.Path = path c.Next() } }
Bitte überprüfen Sie den Codeausschnitt unten. Ich verwende reverseproxy, um zu einer bestimmten Version umzuleiten. Sie müssen eine bestimmte Version sorgfältig überprüfen. Andernfalls kommt es zu rekursiven Aufrufen.
Hinweis: Ich habe zwei Versionen von /user
/user
get(/v1/user
和 /v2/user
get
package main import ( "net/http" "net/http/httputil" "regexp" "github.com/gin-gonic/gin" ) func main() { router := gin.default() router.use(versionmiddleware()) v1 := router.group("/v1") v1.get("/user", func(c *gin.context) { c.string(http.statusok, "this is the v1 api") }) v2 := router.group("/v2") v2.get("/user", func(c *gin.context) { c.string(http.statusok, "this is the v2 api") }) router.run(":8082") } func versionmiddleware() gin.handlerfunc { return func(c *gin.context) { // you need to check c.request.url.path whether // already have a version or not, if it has a valid // version, return. regex, _ := regexp.compile("/v[0-9]+") ver := regex.matchstring(c.request.url.path) if ver { return } version := c.request.header.get("accept-version") // you need to validate given version by the user here. // if version is not a valid version, return error // mentioning that given version is invalid. director := func(req *http.request) { r := c.request req.url.scheme = "http" req.url.host = r.host req.url.path = "/"+ version + r.url.path } proxy := &httputil.reverseproxy{director: director} proxy.servehttp(c.writer, c.request) } }
package main import ( "net/http" "github.com/gin-gonic/gin" "github.com/udayangaac/stackoverflow/golang/75860989/ginwrapper" ) func main() { engine := gin.default() router := ginwrapper.newrouter(engine) defaultrouter := router.default() defaultrouter.get("/profile",func(ctx *gin.context) { }) v1 := router.withversion("/v1") v1.get("/user",func(ctx *gin.context) { ctx.string(http.statusok, "this is the profile v1 api") }) v2 := router.withversion("/v2") v2.get("/user",func(ctx *gin.context) { ctx.string(http.statusok, "this is the profile v2 api") }) engine.run(":8082") }
package ginwrapper import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type router struct { router *gin.engine versiongroups map[string]*gin.routergroup } type versionedrouter struct { version string router } func newrouter(router *gin.engine) *router { return &router{ router: router, versiongroups: make(map[string]*gin.routergroup), } } func (a *router) default() versionedrouter { return versionedrouter{router: *a } } func (a *router) withversion(version string) versionedrouter { if _,ok := a.versiongroups[version]; ok { panic("cannot initialize same version multiple times") } a.versiongroups[version] = a.router.group(version) return versionedrouter{router: *a,version:version } } func (vr versionedrouter) get(relativepath string, handlers ...gin.handlerfunc) { vr.handle(http.methodget,relativepath,handlers...) } // note: you need to follow the same for other http methods. // as an example, we can write a method for post http method as below, // // func (vr versionedrouter) post(relativepath string, handlers ...gin.handlerfunc) { // vr.handle(http.methodpost,relativepath,handlers...) // } func (vr versionedrouter)handle(method,relativepath string, handlers ...gin.handlerfunc) { if !vr.isrouteexist(method,relativepath) { vr.router.handle(method,relativepath,func(ctx *gin.context) { version := ctx.request.header.get("accept-version") if len(version) == 0 { ctx.string(http.statusbadrequest,"accept-version header is empty") } ctx.request.url.path = fmt.sprintf("/%s%s", version, ctx.request.url.path) vr.router.handlecontext(ctx) }) } versionedrelativepath := vr.version + relativepath if !vr.isrouteexist(method,versionedrelativepath) { vr.router.handle(method,versionedrelativepath,handlers... ) } } func (a versionedrouter) isrouteexist(method,relativepath string) bool { for _,route := range a.router.routes() { if route.method == method && relativepath == route.path { return true } } return false }
/v1/user
/v2/user
curl --location 'localhost:8082/user' \ --header 'accept-version: v1'
curl --location 'localhost:8082/user' \ --header 'Accept-version: v2'
Das obige ist der detaillierte Inhalt vonHeaderbasierte Versionierung auf Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!