-
-
Notifications
You must be signed in to change notification settings - Fork 234
feat: significantly reduce dependencies #223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #223 +/- ##
==========================================
+ Coverage 93.37% 94.39% +1.02%
==========================================
Files 17 18 +1
Lines 2189 2606 +417
==========================================
+ Hits 2044 2460 +416
- Misses 106 107 +1
Partials 39 39 ☔ View full report in Codecov by Sentry. |
|
Awesome! This was my primary concern about using huma in production -- managing deps / security exposure / etc is a big deal, and a lot of scanners / tooling aren't smart enough to understand when a source code ref isn't actually compiled into the final binary. Thanks a ton for working so hard on this! |
This fairly substantial PR is an attempt to reduce the dependencies needed to use Huma v2. It uses a combination of building features in-house, copying small utility functions rather than including big deps, and figuring out different approaches to not need to rely on certain de facto standard deps. Read on for details:
github.com/spf13/viperwas used for binding environment variables to command options. Instead, the code now manually checks for these env vars and sets the default on the command option as necessary, no longer needing viper which pulls in tons of deps.github.com/goccy/go-yamlwas used to serialize the OpenAPI to YAML & JSON. It supports the nice,inlinefeature for extensions but is large and pulls in a bunch of other deps. Instead, I built a utility function to help with marshalling JSON using customMarshalJSON() ([]byte, error)methods for the OpenAPI objects. Then I've embedded the tiny json2yaml code that converts the JSON string to a YAML string, allowing me to completely remove any YAML dependency from the project.go.modnow, further reducing the main Huma v2 library'sgo.mod.github.com/danielgtaylor/humav1 was used for benchmarking and examples. The benchmark is now commented out as it's no longer hugely relevant.github.com/danielgtaylor/shorthand/v2andgithub.com/danielgtaylor/mexpr. This is now moved to the examples directory where it belongs as it isn't used anywhere and is just a toy to show the possibilities.int→Int. Instead, this is now completely replaced with a simple unicode-aware uppercase on the first char. This saves pulling down a ton of deps code, over 99% of which was unused.idn-hostnameformat validator doesn't work and is not used, so the attempt to parse such hostnames is removed for now. If this feature is useful/needed I'll add it back in, but will need some failing examples for tests. This used the same deps as above, so saves a good chunk.golang.org/google/uuidis now embedded. We don't need the entire library just to check if a UUID is valid.Starting a brand new project with Huma using the huma.rocks tutorial but with Go 1.22's built-in router (so no Chi external router dependency) you can see quite a difference in dependencies that are pulled down:
vs. after this PR:
So, what's left?
cbor&float16are used to marshal/unmarshal a binary JSON format in the default service config. About 900kb.cobra,pflag, andmousetrapare used for service CLI commands. About 1250kb.casingis used for naming schemas & command options. About 30kb.That leaves about 2mb of source to pull down, which could maybe be improved further. Unfortunately Cobra is part of the API contract, so removing it would be difficult/breaking. CBOR is in the default config so removing that would be hard and probably isn't desired anyway, and embedding casing doesn't save much (if anything). By comparison removing
golang.org/x/text@v0.14.0saved 40mb!Lastly, this slightly improves both the build time and resulting executable size. Using the huma.rocks "Sending data" tutorial code on my M1 pro using
gotipit goes from taking around 4.7s to compile+link to 4.1s (~12% improvement) and the resulting executable size goes from 14mb to 11mb (~20% improvement).Edit: Huma is also now small & fast enough to use in the Go playground where previously it would always cause a timeout. Example using this PR branch to validate some input JSON against a schema: https://go.dev/play/p/OPTg-b5b8zH