danielgtaylor / huma

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

Registering noop operations #528

Open Blinkuu opened 1 month ago

Blinkuu commented 1 month ago

I have a use case where part of the exposed API is reverse-proxied to a downstream server. Currently, this is implemented directly using chi.Router:

func (a *PrometheusApi) Register(router chi.Router) {
    rp := a.metrics.ReverseProxy()

    handler := func(w http.ResponseWriter, r *http.Request) {
        // Reverse proxy logic
        rp.ServeHTTP(w, r)
    }

    router.HandleFunc("/proxy/a", handler)
    router.HandleFunc("/proxy/b", handler)
}

However, I still would like to document this API with Huma fully and have it present under /docs endpoint. In other words, create a "noop" operation that is handled directly by my chi.Router, but still documented using Huma. Is this possible?

danielgtaylor commented 1 month ago

@Blinkuu you can do this by manually adding the information into the OpenAPI since you have full direct access to it. For example:

// Create a new stdlib HTTP router.
mux := http.NewServeMux()

mux.HandleFunc("/example", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, world!"))
})

// Create a Huma v2 API on top of the router.
api := humago.New(mux, huma.DefaultConfig("Demo", "1.0.0"))

api.OpenAPI().Paths = map[string]*huma.PathItem{}
api.OpenAPI().Paths["/example"] = &huma.PathItem{
    Get: &huma.Operation{
        Summary: "Example endpoint",
        Responses: map[string]*huma.Response{
            "200": {
                Description: "Success",
                Content: map[string]*huma.MediaType{
                    "text/plain": {},
                },
            },
        },
    },
}

https://go.dev/play/p/u7KksqFHFCH

Blinkuu commented 1 month ago

@danielgtaylor would it be possible to also run Huma Middleware for such routes, or is this too much of a stretch? I'm trying to marry documentation/Open API spec generation with auth middleware and raw reverse-proxy somehow 😅

danielgtaylor commented 1 month ago

@Blinkuu you could maybe hack it together somehow but remember these routes will not have an associated operation in the middleware as that happens in the Huma layer. I think you might be better off abstracting the middleware to not require Huma and then sharing that between the routes.