danielgtaylor / huma

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

Suggestion: groups and sub-routing #489

Open cardinalby opened 4 months ago

cardinalby commented 4 months 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", ...)
braindev commented 1 month ago

Check out the library and contact me if you would be interested in bringing these features into Huma.

@cardinalby, I'm not sure how to contact you other than here. FWIW, I think the features your library pair well with ❤️ Huma ❤️. My use case is an API protected by an authentication middleware BUT there are some endpoints which do not need or cannot require authentication. It feels weird to break them out in to a separate API OR have to remember to add the authentication middleware for every API endpoint except the few exceptions (which seems error prone).

Consider a contrived example:

# no need for authentication
POST /api/authentication
POST /api/reset_password
POST /api/create_account
GET  /api/plans

# requires authentication
GET  /api/authentication
... everything else
cardinalby commented 1 month ago

@braindev Hi and thanks :) You are right, it's one of the use-cases I created it for. Same as base paths for groups, middlewares are must-have for routing.

P.S. It's the issue I created hoping to contact the Huma author if he is interested in the features from my lib. If you have questions regarding Hureg usage you can create an issue at Hureg's issues page.