Huma & OpenAPI
Modern APIs: Huma & OpenAPI
Writing REST APIs involves two pains: 1. Validation (Checking JSON inputs). 2. Documentation (Keeping Swagger/OpenAPI YAML in sync with code).
In the past, we wrote code, then manually wrote YAML. The YAML effectively lied because it drifted from the code.
Enter Huma
Huma (huma.rocks) is the modern (2025/2026) framework of choice for building APIs. * Code-First OpenAPI: It generates the OpenAPI 3.1 Spec from your Go structs. * Automatic Validation: It validates inputs based on struct tags.
Huma Example
package main
import (
"context"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/go-chi/chi/v5"
)
// 1. Define Request/Response
type GreetingInput struct {
Name string `query:"name" maxLength:"30" doc:"Name to greet"`
}
type GreetingOutput struct {
Body struct {
Message string `json:"message" example:"Hello, World!"`
}
}
func main() {
router := chi.NewMux()
api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))
// 2. Register Operation
huma.Register(api, huma.Operation{
OperationID: "get-greeting",
Method: http.MethodGet,
Path: "/greeting",
Summary: "Get a welcome message",
}, func(ctx context.Context, input *GreetingInput) (*GreetingOutput, error) {
// Only executes if validation passes!
resp := &GreetingOutput{}
resp.Body.Message = "Hello, " + input.Name
return resp, nil
})
http.ListenAndServe(":8888", router)
}Why Huma?
- Documentation: Visit
/docs(or similar) and you get a beautiful, interactive Scalar or Swagger UI automatically. - Safety: Meaningful error messages for users (“Field ‘name’ is too long”).
- Standard Library Compatible: It works on top of
http.ServeMux,Chi, orGin. It doesn’t lock you into a monolithic ecosystem.
This replaces the older swag comment-based generation which was error-prone and brittle.