danielgtaylor / huma

Huma REST/HTTP API Framework for Golang with OpenAPI 3.1
https://huma.rocks/
MIT License
1.71k stars 134 forks source link

Routing groups in Go 1.22 #468

Closed Mike-at-EQT closed 1 month ago

Mike-at-EQT commented 1 month ago

Could you help me understand why the following code is not routed properly to Huma?

Basically, the "/api/" gets stripped and then I end up with just "/" everywhere. I can't call the healthcheck or the OpenAPI docs.


func NewRouter() http.Handler {
    mux := http.NewServeMux()

    mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Welcome to the API 🎉"))
    }))

    mux.Handle("/api/", ApiMux())

    return mux
}

func ApiMux() http.Handler {
    apiMux := http.NewServeMux()

    apiConfig := huma.DefaultConfig("API Service", "1.0.0")
    apiConfig.Servers = []*huma.Server{
        {URL: config.LoadConfig().BaseURL + "/api"},
    }
    api := humago.NewWithPrefix(apiMux, "/api", apiConfig)

    huma.Get(api, "/health", handlers.HandleHealthCheck)

    return apiMux
}
LeeSaferite commented 1 month ago

Your code works fine for me on go 1.22.2 and Huma v2.18.0

package main

import (
    "context"
    "net/http"

    "github.com/danielgtaylor/huma/v2"
    "github.com/danielgtaylor/huma/v2/adapters/humago"
)

func main() {
    server := http.Server{
        Addr:    ":8080",
        Handler: NewRouter(),
    }
    if err := server.ListenAndServe(); err != nil {
        panic(err)
    }
}

func NewRouter() http.Handler {
    mux := http.NewServeMux()

    mux.Handle(
        "/", http.HandlerFunc(
            func(w http.ResponseWriter, r *http.Request) {
                w.Write([]byte("Welcome to the API 🎉"))
            },
        ),
    )

    mux.Handle("/api/", ApiMux())

    return mux
}

func ApiMux() http.Handler {
    apiMux := http.NewServeMux()

    apiConfig := huma.DefaultConfig("API Service", "1.0.0")
    apiConfig.Servers = []*huma.Server{
        {URL: "http://localhost:8080/api"},
    }
    api := humago.NewWithPrefix(apiMux, "/api", apiConfig)
    huma.Get(
        api, "/health", func(ctx context.Context, i *Input) (*Output, error) {
            return &Output{Body: "healthy"}, nil
        },
    )

    return apiMux
}

type Input struct {
}

type Output struct {
    Body string `json:"body"`
}
Mike-at-EQT commented 1 month ago

Thank you @LeeSaferite . I copied and ran your code locally (Go 1.22.4, Huma 2.18.0).

In Chrome (usual window): http://localhost:8080/api/docs becomes http://localhost:8080/docs

In Chrome (private mode): Works!

In curl: Works!

So in other words, there is something fishy going on with my browser that causes URL re-writing :(