Versioning in Go Huma

versioning-in-go-huma

We want to have a separate documentation for each version in Go Huma, e.g. /v1/docs, /v2/docs, etc.

This can be done by setting the docs path like this:

config.DocsPath = "https://dev.to/{version}/docs"

We can use middleware to get the version from the path in the request and load the description used in the docs depending on the version:

config := huma.DefaultConfig("API V"+versionNumberString, versionNumberString+".0.0")
                overviewFilePath := filepath.Join("https://dev.to/app/docs", fmt.Sprintf("v%s", versionNumberString), "overview.md")
                overview, err := ioutil.ReadFile(overviewFilePath)
                if err != nil {
                    log.Fatalf("Error reading file: %v", err)
                }

                config.Info.Description = string(overview)

And we can import all routes that we want to display in the docs based on the version. This will also load them so that they can be used as actual endpoints.

This is the complete code for routing:

router := chi.NewMux()
    router.Use(func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            urlPathParts := strings.Split(r.URL.Path, "/")
            versions := []string{"v1", "v2", "v3"}
            if helpers.Contains(versions, urlPathParts[1]) {
                versionPath := urlPathParts[1]
                if versionPath == "" {
                    http.Error(w, "version does not exist", http.StatusInternalServerError)
                }
                versionNumberString := strings.TrimPrefix(versionPath, "v")
                versionNumber, _ := strconv.Atoi(versionNumberString)
                config := huma.DefaultConfig("API V"+versionNumberString, versionNumberString+".0.0")
                overviewFilePath := filepath.Join("https://dev.to/app/docs", fmt.Sprintf("v%s", versionNumberString), "overview.md")
                overview, err := ioutil.ReadFile(overviewFilePath)
                if err != nil {
                    log.Fatalf("Error reading file: %v", err)
                }

                config.Info.Description = string(overview)
                api := humachi.New(router, config)

                switch versionNumber {
                case 1:
                    api = v1handlers.AddV1Middleware(api)
                    v1handlers.AddV1Routes(api)
                case 2:
                    api = v2handlers.AddV2Middleware(api)
                    v2handlers.AddV2Routes(api)
                default:
                    api = v3handlers.AddV3Middleware(api)
                    router = v3handlers.AddV3ErrorResponses(router)
                    v3handlers.AddV3Routes(api)
                }
            }

            next.ServeHTTP(w, r)
        })
    })

    config := huma.DefaultConfig("API V3", "3.0.0")
    config.DocsPath = "https://dev.to/{version}/docs"

    humachi.New(router, config)
Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
finding-striking-distance-keywords-—-whiteboard-friday

Finding Striking Distance Keywords — Whiteboard Friday

Next Post
ai-first-organization

AI-First Organization

Related Posts
c++-指向類別成員的指位器的實作細節

C++ 指向類別成員的指位器的實作細節

C++ 可以定義指向成員函式的指位器, 不過因為成員函式可能是虛擬函式, 如何能夠透過指向成員函式的指位器達到呼叫正確的成員函式呢?本來就來簡單探究。(本文均以 g++ 為例, 並且只探討單純的單一繼承)。 指向非虛擬函式的指位器 首先來看個簡單的範例, 建立指向非虛擬函式的指位器: #include using namespace std; class A { public:…
Read More