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

Suggestion: groups and sub-routing #489

Open cardinalby opened 4 weeks ago

cardinalby commented 4 weeks ago

Hi! Thanks for the great library, I believe it's the best approach to documenting API in Go ecosystem so far.

Although, I found a batch of issues created by different people here regarding:

Also, some of the features (Transformers) are available only globally for the API instance and can't be set per operation.

OpenAPI endpoints are registered directly with Adapter and I can't apply middlewares to them (how to add auth for openapi.yml endpoint?)

I believe these issues should be addressed by Huma instead of by tuning underlying routers:

I want to use Huma in my company's project, we need all these features to migrate from Gin due to the project structure and heavy usage of gin groups.

I found an elegant way to provide all these features with Huma solely and want you to take a look at it. I believe it can be integrated into Huma with full backward compatibility resolving all the issues you have on Github.

Check out the library and contact me if you would be interested in bringing these features into Huma. I believe it would be even more elegant being a part of Huma rather than a separate library.

Some examples:

🔻 "Base path + tags + middlewares" group

v1gr := api.            // all operations registered with v1gr will have:
    AddBasePath("/v1").                            // - "/v1" base path
    AddOpHandler(op_handler.AddTags("some_tag")).  // - "some_tag" tag
    AddMiddlewares(m1, m2)                         // - m1, m2 middlewares

hureg.Get(v1gr, "/cat", ...) // "/v1/cat" with "some_tag" tag and m1, m2 middlewares
hureg.Get(v1gr, "/dog", ...) // "/v1/dog" with "some_tag" tag and m1, m2 middlewares

🔻 Multiple base paths

Sometimes we need to register the same endpoint with multiple base paths (e.g. /v1 and /v2).

multiPathGr := api.AddMultiBasePaths(nil, "/v1", "/v2")

hureg.Get(multiPathGr, "/sparrow", ...) // "/v1/sparrow"
                                        // "/v2/sparrow"

🔻 Transformers per group

trGr := api.AddTransformers(...) // transformers will be applied only to the operations 
                                 // registered in this group

hureg.Get(trGr, "/crocodile", ...)