huma icon indicating copy to clipboard operation
huma copied to clipboard

Registering noop operations

Open Blinkuu opened this issue 1 year ago • 3 comments

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?

Blinkuu avatar Jul 29 '24 17:07 Blinkuu

@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

danielgtaylor avatar Jul 29 '24 17:07 danielgtaylor

@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 😅

Blinkuu avatar Jul 29 '24 18:07 Blinkuu

@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.

danielgtaylor avatar Jul 30 '24 01:07 danielgtaylor