【问题标题】:Clean way for same endpoints but with different API versions相同端点但具有不同 API 版本的清洁方式
【发布时间】:2021-08-24 16:28:44
【问题描述】:

我正在寻找一种简洁的方法来维护具有相同端点的 API 的两个版本。

现在,最简单但似乎过度的方法是拥有类似的东西

  r := chi.NewRouter()
  r.Get("/test", func(w http.ResponseWriter, r *http.Request) {
    version := r.Header.Get("Accept-version")
    if version == "v1" {
      w.Write([]byte("version 1 of api"))
    } else {
      w.Write([]byte("other version of api"))
    }
  })

但是当你有几十个左右的端点时......可能会变得混乱

我想要的方式是拥有一个中间件,该中间件将通过下一个定义的路线。所以像

  r := chi.NewRouter()
  r.With(UseVersion1).Get("/test", func(w http.ResponseWriter, r *http.Request) {
      w.Write([]byte("version 1 of api"))
    }
  })
  r.With(UseVersion2).Get("/test", func(w http.ResponseWriter, r *http.Request) {
      w.Write([]byte("other version of api"))
    }
  })

这甚至可能吗?或者有人可以建议一条更好的路线(双关语不是故意的)

编辑:我知道为路径添加前缀是一个可行的选择。我想避免这种情况

【问题讨论】:

  • 在路径中添加版本前缀:/v1/test 和 /v2/test。
  • 我忘了说我不想给路径加前缀
  • alexmac 是对的 通常我们使用前缀,但是如果你不想添加前缀你可以使用中间件

标签: rest go go-chi


【解决方案1】:

alexmac 是对的 一般我们都是用prefix的,如果不想加prefix也可以用middleware(ps:不推荐)

你的代码有问题,一个url不能用很多中间件

以下是 gin 中的示例,在 chi 中,您可以编写自己的代码:

package main

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

func Version() gin.HandlerFunc {
    return func(c *gin.Context) {

        if c.Request.RequestURI[:2] != "/v" {
            version := c.GetHeader("Accept-version")
            if version == ""{
                version = "v2"
            }
            c.Redirect(302, "/" + version + c.Request.RequestURI)
            c.Abort()
        }else{
            c.Next()
        }
    }
}

func main() {
    r := gin.New()
    r.Use(Version())
    v1 := r.Group("v1")
    v2 := r.Group("v2")

    v1.GET("/test", func (c *gin.Context){
        c.String(200, "v1 test")
    })
    v2.GET("/test", func (c *gin.Context){
        c.String(200, "v2 test")
    })

    // Listen and serve on 0.0.0.0:8080
    r.Run(":8080")
}

如果您不想更改网址,您可以:

package main

import (
    "github.com/gin-gonic/gin"
)
var(
    r *gin.Engine
)
func Version() gin.HandlerFunc {
    return func(c *gin.Context) {
        if c.Request.URL.Path[:2] != "/v" {
            version := c.GetHeader("Accept-version")
            if version == ""{
                version = "v2"
            }
            c.Request.URL.Path = "/" + version + c.Request.RequestURI
            r.HandleContext(c)
            c.Abort()
        }
        c.Next()
    }
}

func main() {
    r = gin.New()
    r.Use(Version())
    v1 := r.Group("v1")
    v2 := r.Group("v2")
    v1.GET("/test", func (c *gin.Context){
        c.String(200, "v1/test")
    })
    v2.GET("/test", func (c *gin.Context){
        c.String(200, "v2/test")
    })

    // Listen and serve on 0.0.0.0:8080
    r.Run(":8080")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-11
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多