返回顶部
首页 > 资讯 > 后端开发 > GO >golang 上基于标头的版本控制
  • 953
分享到

golang 上基于标头的版本控制

overflow 2024-02-10 20:02:16 953人浏览 薄情痞子
摘要

golang上的基于标头的版本控制是一种在开发过程中管理代码版本的有效方法。通过在代码文件的开头添加版本信息,开发人员可以方便地跟踪代码的变更和版本历史。这种版本控制方法不仅简单易用,

golang上的基于标头的版本控制是一种在开发过程中管理代码版本的有效方法。通过在代码文件的开头添加版本信息,开发人员可以方便地跟踪代码的变更和版本历史。这种版本控制方法不仅简单易用,而且适用于各种规模的项目PHP小编西瓜将在本文中详细介绍Golang上基于标头的版本控制的使用方法和注意事项,帮助开发人员更好地管理和维护代码。无论你是初学者还是有经验的开发者,本文都将为你提供有价值的参考和指导。让我们一起来探索这个有趣而实用的版本控制技术吧!

问题内容

我想使用 gin 在 go 上实现基于标头的版本控制。我正在考虑使用中间件功能在路由器上执行此操作。

客户端将调用相同的 api url,并且版本将位于自定义 Http 标头中,如下所示:

调用版本1 获取/用户/12345678 接受版本:v1

调用版本 2: 获取/用户/12345678 接受版本:v2

因此,路由器可以识别标头并调用特定版本。像这样的事情:

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()
    }
}

解决方法

请检查下面的代码片段。我使用 reverseproxy 重定向到给定的版本。您需要仔细验证给定的版本。否则会导致递归调用。

注意:我使用了两个版本的 /user get/v1/user/v2/user)。

示例代码

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
curl --location 'localhost:8082/user' \
--header 'accept-version: v1'
  • /v2/user
curl --location 'localhost:8082/user' \
--header 'Accept-version: v2'

以上就是golang 上基于标头的版本控制的详细内容,更多请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: golang 上基于标头的版本控制

本文链接: https://lsjlt.com/news/563237.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • golang 上基于标头的版本控制
    Golang上的基于标头的版本控制是一种在开发过程中管理代码版本的有效方法。通过在代码文件的开头添加版本信息,开发人员可以方便地跟踪代码的变更和版本历史。这种版本控制方法不仅简单易用,...
    99+
    2024-02-10
    overflow
  • 基于Python和Django的大数据分析和Git版本控制
    近年来,随着大数据技术的不断发展和普及,越来越多的企业开始注重对数据的分析和挖掘。而Python和Django作为目前最流行的编程语言和Web框架之一,已经成为大数据分析和Git版本控制的首选工具。 Python作为一种简洁、易读、易学的编...
    99+
    2023-07-11
    django 大数据 git
  • golang函数依赖管理与版本控制
    go语言通过go.mod文件和go get命令管理函数依赖关系,并通过语义版本控制和标签提供版本控制。go.mod文件指定了模块版本信息,go get命令用于下载并安装函数。语义版本控制...
    99+
    2024-04-26
    golang 依赖管理 版本控制 git go语言
  • 基于SpringBoot2.0版本与老版本的区别
    目录SpringBoot版本问题这是maven依赖一、解决方案二、解决方案SpringBoot2.0版本新特性 以Java 8 为基准 Spring Boot 2.0 要求Java ...
    99+
    2024-04-02
  • git基础之各版本控制系统介绍
    目录1、什么是版本控制系统2、我们为什么要用版本控制3、版本管理系统的演变(1)本地版本控制系统(2)集中化版本控制系统(3)分布式版本控制系统1、什么是版本控制系统 版本控制是一种...
    99+
    2024-04-02
  • 版本控制器Git的使用。
    目录 一、分布式版本工具 1、基本介绍 2、Git 安装配置 3、本地仓库和基础指令 二、分支 1、分支概述 2、解决冲突 三、Git远程仓库  1、常用的托管服务[远程仓库]   2、配置SSH公钥 3、操作远程仓库 4、解决合并冲突 三...
    99+
    2023-09-10
    git 服务器 svn
  • PHP中的版本控制工具
    PHP语言是现今全球使用最为广泛的后端编程语言之一,因其易学易用、开发效率高等特点深受广大开发者的喜爱和支持。随着时间的推移和PHP语言的不断发展壮大,其版本也在不停地迭代更新。为了更好地管理和维护各个版本的PHP代码,开发者们需要借助各种...
    99+
    2023-05-25
    工具 PHP 版本控制
  • 「从零单排canal 02」 canal集群版 + admin控制台 最新搭建姿势(基于1.1.4版本)
    canal [kə"næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据 订阅 和 消费。应该是阿里云DTS(Data Transfer Service)的开源版本,开源地址: https://gi...
    99+
    2017-06-15
    「从零单排canal 02」 canal集群版 + admin控制台 最新搭建姿势(基于1.1.4版本)
  • Java SVN:版本控制的救世主,拯救代码于灾难
    Java SVN:版本控制的救世主 在软件开发中,代码版本控制至关重要,因为它提供了对代码更改的组织、跟踪和管理。Java SVN(Subversion)是一个流行且功能强大的版本控制系统,为Java开发人员提供了保护项目并简化协作的宝...
    99+
    2024-03-07
    Java SVN、版本控制、代码协作、冲突解决、代码回滚
  • Java基础篇之分布式版本控制工具Git
    目录版本控制版本控制分类1.本地版本控制2.集中版本控制SVN3.分布式版本控制Git和SVN的区别Git的历史:常用的Linux命令Git配置Git基本理论(重要)Git项目搭建本...
    99+
    2024-04-02
  • Git操作指南:如何快速上手版本控制?
    随着软件开发的日益发展,版本控制成为了一个不可或缺的工具。Git作为目前最流行的版本控制工具,被广泛地应用于软件开发、文档管理等领域。本篇文章将为你提供一份Git操作指南,帮助你快速上手版本控制。 一、Git的安装与配置 首先,我们需要安...
    99+
    2023-06-28
    编程算法 开发技术 git
  • 如何在GitLab中进行版本控制和标签管理
    如何在GitLab中进行版本控制和标签管理简介:在软件开发过程中,版本控制是一个重要的环节。GitLab作为一个强大的版本控制系统,为团队协作提供了便利。本文将介绍如何使用GitLab进行版本控制和标签管理,并提供具体的代码示例。一、创建项...
    99+
    2023-10-27
    gitlab 版本控制 标签管理
  • 基于XML的Spring声明事务控制
    Spring框架为我们提供好了事务控制器,我们不必自己写事务控制器。下面就详细说明基于XML配置Spring事务控制器的步骤。 1. 配置事务管理器 <!-- 配置事务管理器 ...
    99+
    2024-04-02
  • idea2019上如何配置gitee以实现代码的版本控制
    本篇内容主要讲解“idea2019上如何配置gitee以实现代码的版本控制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“idea2019上如何配置gitee以实现代码的版本控制”吧!登录 Git...
    99+
    2023-07-05
  • Educoder/头歌JAVA——Java Web:基于JSP的网上商城
    目录 一、商品列表 本关任务 具体要求 结果输出 实现代码 二、商品详情 本关任务 JDBC查询方法封装 商品相关信息介绍 具体要求 结果输出 实现代码 三、商品搜索 编程要求 测试说明 实现代码 四、购物车列表 本关任务 JDBC查询方法...
    99+
    2023-10-19
    java 前端 开发语言
  • 基于Python实现简易的自制头像神器
    目录前言正文1)原理简介2)准备中3)代码展示4)效果展示前言 都说新年新气象,所以,为了迎接2022年的到来! 小编决定换一波头像——于是问题来了!换一个什...
    99+
    2024-04-02
  • ASP.NET Core3.x API版本控制的实现
    前言 一般来说需要更改我们API的时候才考虑版本控制,但是我觉得我们不应该等到那时候来实现它,我们应该有一个版本策略从我们应用程序开发时就开始制定好我们的策略,我们一直遵循着...
    99+
    2022-06-07
    ASP.NET core net api ASP
  • 解密 Java Git:版本控制的革命
    Git 的优势:分散的力量 与集中式 VCS(如 Subversion)不同,Git 采用分布式方法。这消除了对中心服务器的依赖,使每个开发人员拥有自己的代码库副本。这种分散架构提供了以下主要优势: 离线工作:开发人员可以在没有互联网连...
    99+
    2024-04-02
  • C++ 函数命名中的版本控制
    c++++ 函数命名中的版本控制是一种管理代码变更的方法,通过采用以下命名约定实现:旧版本保留原始名称并添加数字后缀,新版本创建相似名称的新函数并增加后缀。优点包括易于理解、向前兼容和回...
    99+
    2024-04-24
    c++ 命名规范
  • 基于Jpa中ManyToMany和OneToMany的双向控制
    目录Jpa ManyToMany和OneToMany的双向控制1、ManyToMany   2、OneToMany以及ManyToOneJPA中ManyToMany关系问题解决办法J...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作