Skip to content

Commit 3aee9bd

Browse files
authored
Additional docs + normalize operation IDs (#974)
* Include docs warning for OpenAPIPath (#834) * Replace spaces in OperationIDs with hyphens (#721) * Add examples of who is using Huma
1 parent e31a819 commit 3aee9bd

10 files changed

Lines changed: 76 additions & 7 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ Official Go package documentation can always be found at https://pkg.go.dev/gith
210210
- [Bump.sh Deploying Docs from Huma](https://docs.bump.sh/guides/bump-sh-tutorials/huma/)
211211
- Mentioned in [Composable HTTP Handlers Using Generics](https://www.willem.dev/articles/generic-http-handlers/)
212212

213+
# Who is using Huma?
214+
215+
Huma is used by many companies and open-source projects. See the [Who is using Huma?](https://huma.rocks/why/#who-is-using-huma) page for a list!
216+
213217
Be sure to star the project if you find it useful!
214218

215219
<a href="https://star-history.com/#danielgtaylor/huma&Date">

README_CN.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ HTTP/1.1 200 OK
184184
- [Bump.sh 从 Huma 部署文档](https://docs.bump.sh/guides/bump-sh-tutorials/huma/)
185185
- [使用泛型的可组合 HTTP 处理程序](https://www.willem.dev/articles/generic-http-handlers/)中提到
186186

187+
# 谁在使用 Huma?
188+
189+
Huma 被许多公司和开源项目所使用。请参阅 [谁在使用 Huma?](https://huma.rocks/why/#who-is-using-huma) 页面查看列表!
190+
187191
如果您觉得该项目有用,请务必为该项目加注星标!
188192

189193
<a href="https://star-history.com/#danielgtaylor/huma&Date">

README_JA.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ HTTP/1.1 200 OK
235235

236236
---
237237

238+
## Humaを使用しているプロジェクト
239+
240+
Humaは多くの企業やオープンソースプロジェクトで使用されています。リストについては、[Humaを使用しているプロジェクト](https://huma.rocks/why/#who-is-using-huma)のページをご覧ください!
241+
242+
---
243+
238244
プロジェクトが役に立った場合はぜひスターをお願いします!
239245

240246
<a href="https://star-history.com/#danielgtaylor/huma&Date">

api.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ type Config struct {
187187

188188
// OpenAPIPath is the path to the OpenAPI spec without extension. If set
189189
// to `/openapi` it will allow clients to get `/openapi.json` or
190-
// `/openapi.yaml`, for example.
190+
// `/openapi.yaml`, for example. Note that some middleware like chi's
191+
// `URLFormat` can interfere with these paths by stripping the extension.
191192
OpenAPIPath string
192193

193194
// DocsPath is the path to the API documentation. If set to `/docs `, it will

docs/docs/features/api-docs.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ You can switch to other documentation renderers using `config.DocsRenderer`. The
2020

2121
You can disable the built-in documentation by setting `config.DocsPath` to an empty string. This allows you to provide your own documentation renderer if you wish.
2222

23+
!!! warning "Middleware Conflicts"
24+
25+
Some middleware can interfere with the documentation renderer's ability to fetch the OpenAPI spec. For example, [go-chi/chi](https://github.com/go-chi/chi)'s `middleware.URLFormat` will rewrite URLs that end in `.json` or `.yaml` (e.g. `/openapi.json` -> `/openapi`), which can lead to 404 errors for the spec. If you encounter this, consider disabling that middleware or configuring it to skip the OpenAPI and documentation paths.
26+
2327
## Customizing Documentation
2428

2529
You can customize the generated documentation by providing your own renderer function to the API adapter or by using the underlying router directly.

docs/docs/features/operations.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ huma.Get(api, "/things/{thing-id}", func(ctx context.Context, input *YourInput)
7171
})
7272
```
7373

74-
In the example above, the generated operation ID is `get-things-by-thing-id` with a summary of `Get things by id`. To customize these, override `huma.GenerateOperationID(method, path string, response any)` for operation IDs and `huma.GenerateSummary(method, path string, response any)` for summaries.
74+
In the example above, the generated operation ID is `get-things-by-thing-id` with a summary of `Get things by id`. Note that any spaces in an operation ID will be automatically replaced with hyphens (e.g. `my operation` becomes `my-operation`) to ensure compatibility with various tools.
75+
76+
To customize these, override `huma.GenerateOperationID(method, path string, response any)` for operation IDs and `huma.GenerateSummary(method, path string, response any)` for summaries.
7577

7678
This makes it easy to get started, particularly if coming from other frameworks, and you can simply switch to using `huma.Register` if/when you need to set additional fields on the operation.
7779

docs/docs/tutorial/client-sdks.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ Congratulations! You just learned:
168168
- How to generate a Go SDK for your API
169169
- How to build a client using the SDK to call the API
170170

171+
## External Resources
172+
173+
For a more in-depth real-world example, check out [How to build an API with Go and Huma](https://zuplo.com/blog/how-to-build-an-api-with-go-and-huma) on the Zuplo blog. It covers:
174+
175+
- Creating a new Huma project & defining some endpoints
176+
- Setting up MongoDB
177+
- Running the service
178+
- Hosting our API
179+
- Creating a project on Zuplo
180+
- Setting up API key authentication
181+
171182
## Dive Deeper
172183

173184
Want to learn more about OpenAPI tooling like SDK generators and how to use them? Check these out next:

docs/docs/why/index.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,25 @@ Huma provides guardrails & automation to keep your team and your services runnin
9696
- Supports automatic CLI & SDK generation
9797

9898
[:material-arrow-right: Start the tutorial now](../tutorial/installation.md)
99+
100+
## Who is using Huma?
101+
102+
Huma is used by a variety of companies and projects, from large-scale production services handling millions of requests to community-driven open-source tools.
103+
104+
### Production at Scale
105+
106+
Huma powers critical services for some of the largest companies in the world:
107+
108+
- **Corporate Adoption**: We see regular traffic and adoption from **FinTechs**, **Mercedes-Benz**, and many other global companies.
109+
- **Roblox**: The content catalog service uses Huma and handles over a **million requests a second** in production.
110+
- **Warner Bros. Discovery**: Used to run major live events and services including the **Olympics**, **March Madness**, **CNN**, and more.
111+
112+
### Open Source Projects
113+
114+
The following is a list of open-source projects using Huma. If you would like to see your project listed here, please [open a pull request](https://github.com/danielgtaylor/huma/pulls) or [issue](https://github.com/danielgtaylor/huma/issues) to request it!
115+
116+
- [AvengeMedia - dgop](https://github.com/AvengeMedia/dgop)
117+
- [ckoliber - GoCRUD](https://github.com/ckoliber/gocrud)
118+
- [fy0 - CodeKanban](https://github.com/fy0/CodeKanban)
119+
- [Global Cyber Alliance - Domain Security Scanner](https://github.com/globalcyberalliance/domain-security-scanner)
120+
- [Mozilla AI - MCPD](https://github.com/mozilla-ai/mcpd)

openapi.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"maps"
77
"net/http"
88
"reflect"
9+
"strings"
910
"time"
1011

1112
"github.com/danielgtaylor/huma/v2/yaml"
@@ -1501,7 +1502,14 @@ type OpenAPI struct {
15011502
// properly added to the Paths map and will call any registered OnAddOperation
15021503
// functions.
15031504
func (o *OpenAPI) AddOperation(op *Operation) {
1504-
// Check this won't create a duplicate operation ID.
1505+
// Normalize spaces in operation ID as some tools (e.g., Stoplight) do not
1506+
// handle them correctly and may redirect or fail to render the operation.
1507+
op.OperationID = strings.ReplaceAll(op.OperationID, " ", "-")
1508+
1509+
if o.Paths == nil {
1510+
o.Paths = map[string]*PathItem{}
1511+
}
1512+
15051513
if op.OperationID != "" {
15061514
for _, pathItem := range o.Paths {
15071515
for _, existingOp := range []*Operation{
@@ -1515,10 +1523,6 @@ func (o *OpenAPI) AddOperation(op *Operation) {
15151523
}
15161524
}
15171525

1518-
if o.Paths == nil {
1519-
o.Paths = map[string]*PathItem{}
1520-
}
1521-
15221526
item := o.Paths[op.Path]
15231527
if item == nil {
15241528
item = &PathItem{}

openapi_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,14 @@ func TestAddOperationForceUniqueOperationIDs(t *testing.T) {
283283
})
284284
})
285285
}
286+
287+
func TestAddOperationNormalizeOperationIDs(t *testing.T) {
288+
oapi := &huma.OpenAPI{}
289+
oapi.AddOperation(&huma.Operation{
290+
OperationID: "test with spaces",
291+
Method: http.MethodGet,
292+
Path: "/test",
293+
})
294+
295+
assert.Equal(t, "test-with-spaces", oapi.Paths["/test"].Get.OperationID)
296+
}

0 commit comments

Comments
 (0)