### Install Restish on Windows Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/cli-client.md Install Restish on Windows using Go or by downloading a release from GitHub. ```bash # Go $ go install github.com/rest-sh/restish/v2/cmd/restish@latest ``` -------------------------------- ### Create Golang REST API with Huma Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/your-first-api.md This Go code snippet demonstrates how to create a basic REST API using the Huma library. It sets up a Chi router, initializes the Huma API, registers a GET endpoint for greetings, and starts the HTTP server. Dependencies include 'github.com/danielgtaylor/huma/v2' and its adapters and formats. ```go package main import ( "context" "fmt" "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/go-chi/chi/v5" _ "github.com/danielgtaylor/huma/v2/formats/cbor" ) // GreetingOutput represents the greeting operation response. type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } func main() { // Create a new router & API router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // Register GET /greeting/{name} huma.Register(api, huma.Operation{ OperationID: "get-greeting", Method: http.MethodGet, Path: "/greeting/{name}", Summary: "Get a greeting", Description: "Get a greeting for a person by name.", Tags: []string{"Greetings"}, }, func(ctx context.Context, input *struct{ Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"` }) (*GreetingOutput, error) { resp := &GreetingOutput{} resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name) return resp, nil }) // Start the server! http.ListenAndServe("127.0.0.1:8888", router) } ``` -------------------------------- ### Basic Hello World API in Huma (Go) Source: https://github.com/danielgtaylor/huma/blob/main/README.md A complete basic hello world example in Huma, showing how to initialize a Huma app with CLI, declare a resource operation, and define its handler function. This example uses the humachi adapter and chi router. It requires Go 1.22+ and the huma/v2 library. ```go package main import ( "context" "fmt" "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" _ "github.com/danielgtaylor/huma/v2/formats/cbor" ) // Options for the CLI. Pass `--port` or set the `SERVICE_PORT` env var. type Options struct { Port int `help:"Port to listen on" short:"p" default:"8888"` } // GreetingOutput represents the greeting operation response. type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } func main() { // Create a CLI app which takes a port option. cli := humacli.New(func(hooks humacli.Hooks, options *Options) { // Create a new router & API router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // Add the operation handler to the API. huma.Get(api, "/greeting/{name}", func(ctx context.Context, input *struct{ Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"` }) (*GreetingOutput, error) { resp := &GreetingOutput{} resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name) return resp, nil }) // Tell the CLI how to start your router. hooks.OnStart(func() { http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router) }) }) // Run the CLI. When passed no commands, it starts the server. cli.Run() } ``` -------------------------------- ### Install Huma via Go Modules Source: https://github.com/danielgtaylor/huma/blob/main/README.md The installation command for the Huma framework using the Go toolchain. It requires Go version 1.25 or newer and should be executed within a project initialized with go mod. ```shell go get -u github.com/danielgtaylor/huma/v2 ``` -------------------------------- ### Install Restish on Linux Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/cli-client.md Install Restish on Linux using Go, Homebrew, or by downloading a release. ```bash # Go $ go install github.com/rest-sh/restish/v2/cmd/restish@latest # Homebrew for Linux $ brew install restish ``` -------------------------------- ### Testing the Huma API Example (Shell) Source: https://github.com/danielgtaylor/huma/blob/main/README.md Commands to test the basic Huma API example. This includes running the Go application and making a sample request using Restish. The output shows a successful HTTP 200 response with the generated JSON message. ```sh # Get the message from the server $ restish :8888/greeting/world HTTP/1.1 200 OK ... { $schema: "http://localhost:8888/schemas/GreetingOutputBody.json", message: "Hello, world!" } ``` -------------------------------- ### Go Conditional Request Example Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/conditional-requests.md Demonstrates how to implement a conditional GET request in Go using the huma/v2/conditional package. It shows how to check for conditional parameters, retrieve ETag and last modified time, and handle precondition failures by returning a 304 Not Modified response. This example assumes you have a YourOutput type defined elsewhere. ```go huma.Register(api, huma.Operation{ OperationID: "get-resource", Method: http.MethodGet, Path: "/resource", Summary: "Get a resource", }, func(ctx context.Context, input struct { conditional.Params }) (*YourOutput, error) { if input.HasConditionalParams() { // TODO: Get the ETag and last modified time from the resource. etag := "" modified := time.Time{} // If preconditions fail, abort the request processing. Response status // codes are already set for you, but you can optionally provide a body. // Returns an HTTP 304 not modified. if err := input.PreconditionFailed(etag, modified); err != nil { return err } // Otherwise do the normal request processing here... // ... } }) ``` -------------------------------- ### Register Server Start and Stop Hooks (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli.md This Go code snippet illustrates how to register hooks for starting and stopping an HTTP server within the Huma CLI. It sets up the server and defines actions for graceful startup and shutdown. ```go package main import ( "context" "fmt" "net/http" "time" "github.com/danielgtaylor/huma/v2/humacli" ) type Options struct { Port int `doc:"Port to listen on." short:"p" default:"8888"` } func main() { cli := humacli.New(func(hooks humacli.Hooks, options *Options) { // Set up the router and API // ... router := http.NewServeMux() // Create the HTTP server. server := http.Server{ Addr: fmt.Sprintf(":%d", options.Port), Handler: router, } hooks.OnStart(func() { // Start your server here fmt.Println("Server starting...") server.ListenAndServe() }) hooks.OnStop(func() { // Gracefully shutdown your server here fmt.Println("Server shutting down...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() server.Shutdown(ctx) }) }) cli.Run() } ``` -------------------------------- ### Write API Tests in Go using humatest Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/writing-tests.md This Go code snippet demonstrates how to write unit tests for your Huma API using the `humatest` package. It shows how to create a test API instance, register routes using the `addRoutes` function, and then make GET and POST requests to verify responses and status codes. It also includes an example of testing error cases. ```go package main import ( "strings" "testing" "github.com/danielgtaylor/huma/v2/humatest" ) func TestGetGreeting(t *testing.T) { _, api := humatest.New(t) addRoutes(api) resp := api.Get("/greeting/world") if !strings.Contains(resp.Body.String(), "Hello, world!") { t.Fatalf("Unexpected response: %s", resp.Body.String()) } } func TestPutReview(t *testing.T) { _, api := humatest.New(t) addRoutes(api) resp := api.Post("/reviews", map[string]any{ "author": "daniel", "rating": 5, }) if resp.Code != 201 { t.Fatalf("Unexpected status code: %d", resp.Code) } } func TestPutReviewError(t *testing.T) { _, api := humatest.New(t) addRoutes(api) resp := api.Post("/reviews", map[string]any{ "rating": 10, }) if resp.Code != 422 { t.Fatalf("Unexpected status code: %d", resp.Code) } } ``` -------------------------------- ### Run Service CLI with Arguments (Shell) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli.md This example shows how to execute a Go service CLI with different command-line arguments. It demonstrates running with default values and then overriding them with specific flags. ```sh // Run with defaults $ go run main.go I was run with debug:false host: port:8888 // Run with options $ go run main.go --debug=true --host=localhost --port=8000 I was run with debug:true host:localhost port:8000 ``` -------------------------------- ### Configure CLI Auto-Configuration Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli-auto-config.md Use the 'x-cli-config' extension in OpenAPI to provide parameters for CLI tools to auto-configure themselves. This example shows how to set up OAuth2 security and pass client-specific details. ```go o := api.OpenAPI() o.Components.SecuritySchemes["my-scheme"] = &huma.SecurityScheme{ Type: "oauth2", // ... security scheme definition ... } o.Extensions["x-cli-config"] = huma.AutoConfig{ Security: "my-scheme", Params: map[string]string{ "client_id": "abc123", "authorize_url": "https://example.tld/authorize", "token_url": "https://example.tld/token", "scopes": "read,write", } } ``` -------------------------------- ### Install Restish on Mac Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/cli-client.md Install Restish on macOS using Homebrew or Go. Alternatively, download a release from GitHub. ```bash # Homebrew $ brew install restish # Go $ go install github.com/rest-sh/restish/v2/cmd/restish@latest ``` -------------------------------- ### Shell Command Example for Field Selection Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/response-transformers.md A shell command example demonstrating how to use the `FieldSelectTransform` by sending a 'Fields' header with the request. This allows clients to specify which fields they want in the response. ```sh $ restish example.com/things/1 -H 'Fields: {id, tag_names: tags[].name}' ``` -------------------------------- ### Make HTTP Requests Against a Test API Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/test-utilities.md Illustrates how to make various HTTP requests (GET, PUT) against a test API instance using convenience methods like `Get` and `Put`. It also explains how arguments are interpreted as headers, raw bodies, or JSON bodies. ```go func TestMyAPI(t *testing.T) { router, api := humatest.New(t) // Register routes... addRoutes(api) // Make a GET request resp := api.Get("/some/path?foo=bar") // Make a PUT request resp = api.Put("/some/path", "My-Header: abc123", map[string]any{ "author": "daniel", "rating": 5, }) } ``` -------------------------------- ### Define API Skeleton with Huma Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/why/what-about-design-first.md This Go example demonstrates how to define API models and register operations using Huma. It shows a skeleton implementation for a Pet Store API, including data structures and route handlers that can be used to generate an OpenAPI specification. ```go package main import ( "context" "fmt" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" "github.com/spf13/cobra" ) type Category struct { ID int `json:"id" example:"1" doc:"Category ID"` Name string `json:"name" example:"Cats" doc:"Category name"` } type Tag struct { ID int `json:"id" example:"1" doc:"Tag ID"` Name string `json:"name" example:"cute" doc:"Tag name"` } type Pet struct { ID int `json:"id" example:"1" doc:"Pet ID"` Category *Category `json:"category" doc:"Category that the pet belongs to"` Name string `json:"name" example:"Fluffy" doc:"Pet name"` PhotoURLs []string `json:"photoUrls" example:"https://example.com/fluffy.jpg" doc:"Photo URLs for the pet"` Tags []Tag `json:"tags" example:'["cute"]' doc:"Tags for the pet"` Status string `json:"status" example:"available" doc:"Pet status" enum:"available,pending,sold"` } type PetID struct { ID int `path:"petId" example:"1" doc:"Pet ID"` } func main() { var api huma.API cli := humacli.New(func(hooks humacli.Hooks, options *struct{}) { router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("Pet Store", "1.0.0")) huma.Register(api, huma.Operation{ OperationID: "post-pet", Method: "POST", Path: "/pet", Summary: "Add a new pet", }, func(ctx context.Context, input *struct { Body Pet }) (*struct{}, error) { return nil, nil }) huma.Register(api, huma.Operation{ OperationID: "get-pet", Method: "GET", Path: "/pet/{petId}", Summary: "Get a pet", }, func(ctx context.Context, input *PetID) (*struct { Body Pet }, error) { return nil, nil }) huma.Register(api, huma.Operation{ OperationID: "find-pet-by-status", Method: "GET", Path: "/pet/findByStatus", Summary: "Find a pet by status", }, func(ctx context.Context, input *struct { Status string `path:"status" example:"available" doc:"Status to filter by" enum:"available,pending,sold"` }) (*struct { Body []Pet }, error) { return nil, nil }) }) cli.Root().AddCommand(&cobra.Command{ Use: "openapi", Run: func(cmd *cobra.Command, args []string) { b, err := api.OpenAPI().MarshalJSON() if err != nil { panic(err) } fmt.Println(string(b)) }, }) cli.Run() } ``` -------------------------------- ### Full Example: Huma API with Custom Validation and Resolvers (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/how-to/custom-validation.md A comprehensive Go example showcasing a Huma API that utilizes custom validation with resolvers for path, query, header, and body parameters. It demonstrates how to define custom types with validation logic and integrate them into an API endpoint. ```go // This example shows how to use resolvers to provide additional validation // for params and body fields, and how exhaustive errors are returned. // // # Example call returning seven errors // restish put :8888/count/3?count=15 -H Count:-3 count:9, nested.subCount: 6 // // # Example success // restish put :8888/count/1 count:2, nested.subCount: 4 package main import ( "context" "fmt" "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" ) // Options for the CLI. type Options struct { Port int `doc:"Port to listen on." short:"p" default:"8888" } // Create a new input type with additional validation attached to it. type IntNot3 int // Resolve is called by Huma to validate the input. Prefix is the current // path like `path.to[3].field`, e.g. `query.count` or `body.nested.subCount`. // Resolvers can also be attached to structs to provide validation across // multiple field combinations, e.g. "if foo is set then bar must be a // multiple of foo's value". Use `prefix.With("bar")` in that scenario. func (i IntNot3) Resolve(ctx huma.Context, prefix *huma.PathBuffer) []error { if i != 0 && i%3 == 0 { return []error{&huma.ErrorDetail{ Location: prefix.String(), Message: "Value cannot be a multiple of three", Value: i, }} } return nil } // Ensure our resolver meets the expected interface. var _ huma.ResolverWithPath = (*IntNot3)(nil) func main() { // Create the CLI, passing a function to be called with your custom options // after they have been parsed. cli := humacli.New(func(hooks humacli.Hooks, options *Options) { router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // Register the greeting operation. huma.Register(api, huma.Operation{ OperationID: "put-count", Summary: "Put a count of things", Method: http.MethodPut, Path: "/count/{count}", }, func(ctx context.Context, input *struct { PathCount IntNot3 `path:"count" example:"2" minimum:"1" maximum:"10" QueryCount IntNot3 `query:"count" example:"2" minimum:"1" maximum:"10" HeaderCount IntNot3 `header:"Count" example:"2" minimum:"1" maximum:"10" Body struct { Count IntNot3 `json:"count" example:"2" minimum:"1" maximum:"10" Nested *struct { SubCount IntNot3 `json:"subCount" example:"2" minimum:"1" maximum:"10" } `json:"nested,omitempty" } }) (*struct{}, error) { fmt.Printf("Got input: %+v\n", input) return nil, nil }) // Tell the CLI how to start your router. hooks.OnStart(func() { // Start the server http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router) }) }) // Run the CLI. When passed no commands, it starts the server. cli.Run() } ``` -------------------------------- ### Streaming Response Example Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/response-streaming.md Demonstrates how to stream data back to the client using a callback function and huma.StreamResponse. ```APIDOC ## Streaming Response Example ### Description This endpoint demonstrates how to stream data back to the client using a long-lived connection. It utilizes a callback function within `huma.StreamResponse` to write data incrementally. ### Method POST (or other methods as applicable to your handler) ### Endpoint [Your specific endpoint path] ### Parameters #### Path Parameters None specified in the example. #### Query Parameters None specified in the example. #### Request Body - **input** (*MyInput) - Required - The input structure for the handler. ### Request Example ```json { "example": "Your request body here" } ``` ### Response #### Success Response (200) - **StreamResponse** (*huma.StreamResponse) - The response object containing the streaming body. #### Response Example ```go func handler(ctx context.Context, input *MyInput) (*huma.StreamResponse, error) { return &huma.StreamResponse{ Body: func(ctx huma.Context) { // Write header info before streaming the body. ctx.SetHeader("Content-Type", "text/my-stream") writer := ctx.BodyWriter() // Update the write deadline to give us extra time. if d, ok := writer.(interface{ SetWriteDeadline(time.Time) error }); ok { d.SetWriteDeadline(time.Now().Add(5 * time.Second)) } else { fmt.Println("warning: unable to set write deadline") } // Write the first message, then flush and wait. writer.Write([]byte("Hello, I'm streaming!")) if f, ok := writer.(http.Flusher); ok { f.Flush() } else { fmt.Println("error: unable to flush") } time.Sleep(3 * time.Second) // Write the second message. writer.Write([]byte("Hello, I'm still streaming!")) }, }, nil } ``` ### Further Reading - [`huma.Context`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#Context) - [`huma.StreamResponse`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#StreamResponse) - [`http.ResponseController`](https://pkg.go.dev/net/http#ResponseController) ``` -------------------------------- ### POST /pet Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/why/what-about-design-first.md Adds a new pet to the store. This operation is part of the Pet Store API example. ```APIDOC ## POST /pet ### Description Adds a new pet to the store. ### Method POST ### Endpoint /pet ### Parameters #### Request Body - **Body** (Pet) - Required - The pet object to add. ### Request Example ```json { "id": 1, "category": { "id": 1, "name": "Cats" }, "name": "Fluffy", "photoUrls": [ "https://example.com/fluffy.jpg" ], "tags": [ { "id": 1, "name": "cute" } ], "status": "available" } ``` ### Response #### Success Response (200) - **Body** (*struct { }*) - This endpoint does not return a response body on success. #### Response Example ```json null ``` ``` -------------------------------- ### Go Image Response with Huma Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/how-to/image-response.md This Go code snippet demonstrates how to register an API endpoint using the Huma framework that returns an image. It utilizes a byte slice for the response body and specifies the 'Content-Type' header to 'image/png'. The example uses the humachi adapter with the chi router. ```go package main import ( "context" "fmt" "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" ) // Options for the CLI. type Options struct { Port int `help:"Port to listen on" short:"p" default:"8888"` } // ImageOutput represents the image operation response. type ImageOutput struct { ContentType string `header:"Content-Type"` Body []byte } func main() { // Create a CLI app which takes a port option. cli := humacli.New(func(hooks humacli.Hooks, options *Options) { // Create a new router & API router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // Register GET /image huma.Register(api, huma.Operation{ OperationID: "get-image", Summary: "Get an image", Method: http.MethodGet, Path: "/image", Responses: map[string]*huma.Response{ "200": { Description: "Image response", Content: map[string]*huma.MediaType{ "image/jpeg": {}, }, }, }, }, func(ctx context.Context, input *struct{}) (*ImageOutput, error) { resp := &ImageOutput{} resp.ContentType = "image/png" resp.Body = []byte{ /* ... image bytes here ... */ } return resp, nil }) // Tell the CLI how to start your server. hooks.OnStart(func() { fmt.Printf("Starting server on port %d...\n", options.Port) http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router) }) }) // Run the CLI. When passed no commands, it starts the server. cli.Run() } ``` -------------------------------- ### Go FieldSelectTransform Example Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/response-transformers.md An example Go function demonstrating a response transformer that selectively returns fields based on a 'Fields' header. It uses JSON marshaling and unmarshaling to process the response data. This can be inefficient and alternative methods should be considered. ```go import ( "encoding/json" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/shorthand" ) // FieldSelectTransform is an example of a transform that can use an input // header value to modify the response on the server, providing a GraphQL-like // way to send only the fields that the client wants over the wire. func FieldSelectTransform(ctx huma.Context, status string, v any) (any, error) { if fields := ctx.Header("Fields"); fields != "" { // Ugh this is inefficient... consider other ways of doing this :-( var tmp any b, _ := json.Marshal(v) json.Unmarshal(b, &tmp) result, _, err := shorthand.GetPath(fields, tmp, shorthand.GetOptions{}) return result, err } return v, nil } ``` -------------------------------- ### Pass Options via Command Line and Environment Variables (Bash) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli.md This bash example demonstrates different ways to pass options to the Huma service CLI. It shows using command-line arguments, short arguments, and environment variables, highlighting precedence rules. ```bash # Example passing command-line args $ go run main.go --port=8000 # Short arguments are also supported $ go run main.go -p 8000 # Example passing by environment variables $ SERVICE_PORT=8000 go run main.go ``` -------------------------------- ### Define Greeting Response Model (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/your-first-api.md Defines the output structure for the greeting API, including a 'message' field in the JSON body. The 'example' and 'doc' tags are used for OpenAPI documentation. ```go package main // GreetingOutput represents the greeting operation response. type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } ``` -------------------------------- ### JSON Response with $schema Property Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/json-schema-registry.md This JSON example demonstrates a response object that includes a '$schema' property, linking to its JSON Schema definition. This enables features like editor validation and code completion. ```json { "$schema": "http://localhost:8888/schemas/Note.json", "title": "I am a note title", "contents": "Example note contents", "labels": ["todo"] } ``` -------------------------------- ### Huma API with Chi Route Groups and Base URLs Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/bring-your-own-router.md This Go example demonstrates how to integrate Huma with Chi's route grouping feature. It sets a base URL for the API and configures Huma's OpenAPI servers accordingly. This allows for proper URL generation in documentation and schemas when using route groups. ```go mux := chi.NewMux() mux.Route("/api", func(r chi.Router) { config := huma.DefaultConfig("My API", "1.0.0") config.Servers = []*huma.Server{ {URL: "https://example.com/api"}, } api = humachi.New(r, config) // Register operations... huma.Get(api, "/demo", func(ctx context.Context, input *struct{}) (*struct{}, error) { // TODO: Implement me! return nil, nil }) }) http.ListenAndServe("localhost:8888", mux) ``` -------------------------------- ### Implement Request Resolver with Input Transformation (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/request-resolvers.md Demonstrates how to implement the huma.Resolver interface to transform input data and access request context. This example shows how to set the Host from the context and transform the Name field using strings.Title. It then registers this resolver with an API operation. ```go package main import ( "context" "fmt" http "net/http" "strings" huma "github.com/danielgtaylor/huma/v2" ) // MyInput demonstrates inputs/transformation type MyInput struct { Host string Name string `query:"name"` } func (m *MyInput) Resolve(ctx huma.Context) []error { // Get request info you don't normally have access to. m.Host = ctx.Host() // Transformations or other data validation m.Name = strings.Title(m.Name) return nil } // Placeholder for YourOutput struct type YourOutput struct {} func main() { // Example API setup (replace with your actual API setup) api := huma.NewAPI(nil, nil) // Then use it like any other input struct: huma.Register(api, huma.Operation{ OperationID: "list-things", Method: http.MethodGet, Path: "/things", Summary: "Get a filtered list of things", }, func(ctx context.Context, input *MyInput) (*YourOutput, error) { fmt.Printf("Host: %s\n", input.Host) fmt.Printf("Name: %s\n", input.Name) return &YourOutput{}, nil }) } ``` -------------------------------- ### Implement Graceful Shutdown with Huma CLI Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/how-to/graceful-shutdown.md This example demonstrates how to use the humacli.Hooks.OnStop method to shut down an HTTP server gracefully. It uses a context with a timeout to allow existing requests to finish processing before the server terminates. ```go package main import ( "context" "fmt" "net/http" "time" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" ) type Options struct { Port int `help:"Port to listen on" short:"p" default:"8888"` } type GreetingInput struct { Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"` } type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } func main() { cli := humacli.New(func(hooks humacli.Hooks, options *Options) { router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) huma.Register(api, huma.Operation{ OperationID: "get-greeting", Summary: "Get a greeting", Method: http.MethodGet, Path: "/greeting/{name}", }, func(ctx context.Context, input *GreetingInput) (*GreetingOutput, error) { resp := &GreetingOutput{} resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name) return resp, nil }) server := http.Server{ Addr: fmt.Sprintf(":%d", options.Port), Handler: router, } hooks.OnStart(func() { server.ListenAndServe() }) hooks.OnStop(func() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() server.Shutdown(ctx) }) }) cli.Run() } ``` -------------------------------- ### Call API with Curl (Bash) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/your-first-api.md Demonstrates how to make a GET request to the Huma API using curl to retrieve a greeting. This command tests the '/greeting/{name}' endpoint with 'world' as the name parameter. ```bash # Get a greeting from the API $ curl http://localhost:8888/greeting/world ``` -------------------------------- ### Register API Routes in Go Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/writing-tests.md This Go code snippet demonstrates how to register API routes (GET /greeting/{name} and POST /reviews) using the Huma library. It defines input and output structures for the operations and separates route registration into a dedicated function `addRoutes` for better testability. ```go package main import ( "context" "fmt" "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/danielgtaylor/huma/v2/humacli" "github.com/go-chi/chi/v5" _ "github.com/danielgtaylor/huma/v2/formats/cbor" ) // Options for the CLI. type Options struct { Port int `help:"Port to listen on" short:"p" default:"8888"` } // GreetingOutput represents the greeting operation response. type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } // ReviewInput represents the review operation request. type ReviewInput struct { Body struct { Author string `json:"author" maxLength:"10" doc:"Author of the review"` Rating int `json:"rating" minimum:"1" maximum:"5" doc:"Rating from 1 to 5"` Message string `json:"message,omitempty" maxLength:"100" doc:"Review message"` } } func addRoutes(api huma.API) { // Register GET /greeting/{name} huma.Register(api, huma.Operation{ OperationID: "get-greeting", Method: http.MethodGet, Path: "/greeting/{name}", Summary: "Get a greeting", Description: "Get a greeting for a person by name.", Tags: []string{"Greetings"}, }, func(ctx context.Context, input *struct{ Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"` }) (*GreetingOutput, error) { resp := &GreetingOutput{} resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name) return resp, nil }) // Register POST /reviews huma.Register(api, huma.Operation{ OperationID: "post-review", Method: http.MethodPost, Path: "/reviews", Summary: "Post a review", Tags: []string{"Reviews"}, DefaultStatus: http.StatusCreated, }, func(ctx context.Context, i *ReviewInput) (*struct{}, error) { // TODO: save review in data store. return nil, nil }) } func main() { // Create a CLI app which takes a port option. cli := humacli.New(func(hooks humacli.Hooks, options *Options) { // Create a new router & API router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) addRoutes(api) // Tell the CLI how to start your server. hooks.OnStart(func() { fmt.Printf("Starting server on port %d...\n", options.Port) http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router) }) }) // Run the CLI. When passed no commands, it starts the server. cli.Run() } ``` -------------------------------- ### GET /resource/{id} Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/operations.md Example of a convenience method for retrieving a resource using the Huma framework. ```APIDOC ## GET /resource/{id} ### Description Retrieves a specific resource by its identifier using the convenience method huma.Get. ### Method GET ### Endpoint /resource/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the resource. ### Request Example N/A ### Response #### Success Response (200) - **data** (object) - The requested resource object. #### Response Example { "id": "123", "name": "Example Resource" } ``` -------------------------------- ### GET /pet/findByStatus Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/why/what-about-design-first.md Finds pets based on their status. This endpoint is part of the Pet Store API example. ```APIDOC ## GET /pet/findByStatus ### Description Finds pets based on their status. ### Method GET ### Endpoint /pet/findByStatus ### Parameters #### Query Parameters - **status** (string) - Required - Status to filter by. Allowed values: available, pending, sold. ### Request Example ```json { "status": "available" } ``` ### Response #### Success Response (200) - **Body** ([]Pet) - A list of pets matching the specified status. #### Response Example ```json [ { "id": 1, "category": { "id": 1, "name": "Cats" }, "name": "Fluffy", "photoUrls": [ "https://example.com/fluffy.jpg" ], "tags": [ { "id": 1, "name": "cute" } ], "status": "available" } ] ``` ``` -------------------------------- ### Initialize Router and Huma API (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/your-first-api.md Sets up a Chi router and a Huma API instance for handling requests. It includes necessary imports and the basic server startup logic. An alternative using Go's built-in http.ServeMux is also shown. ```go package main import ( "net/http" "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/go-chi/chi/v5" _ "github.com/danielgtaylor/huma/v2/formats/cbor" ) // GreetingOutput represents the greeting operation response. type GreetingOutput struct { Body struct { Message string `json:"message" example:"Hello, world!" doc:"Greeting message"` } } func main() { // Create a new router & API router := chi.NewMux() api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // TODO: Register operations... // Start the server! http.ListenAndServe("127.0.0.1:8888", router) } ``` ```go router := http.NewServeMux() api := humago.New(router, huma.DefaultConfig("My API", "1.0.0")) ``` -------------------------------- ### GET /pet/{petId} Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/why/what-about-design-first.md Retrieves a specific pet by its ID. This endpoint is part of the Pet Store API example. ```APIDOC ## GET /pet/{petId} ### Description Retrieves a pet by its ID. ### Method GET ### Endpoint /pet/{petId} ### Parameters #### Path Parameters - **petId** (int) - Required - The ID of the pet to retrieve. ### Request Example ```json { "petId": 1 } ``` ### Response #### Success Response (200) - **Body** (Pet) - The pet object. #### Response Example ```json { "id": 1, "category": { "id": 1, "name": "Cats" }, "name": "Fluffy", "photoUrls": [ "https://example.com/fluffy.jpg" ], "tags": [ { "id": 1, "name": "cute" } ], "status": "available" } ``` ``` -------------------------------- ### Define and Run Service CLI Options (Go) Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli.md This Go code snippet demonstrates how to define input options for a service CLI using a struct with documentation tags. It then initializes and runs the CLI, printing the provided options. ```go package main import ( "fmt" "github.com/danielgtaylor/huma/v2/humacli" ) // First, define your input options. type Options struct { Debug bool `doc:"Enable debug logging"` Host string `doc:"Hostname to listen on."` Port int `doc:"Port to listen on." short:"p" default:"8888"` } func main() { // Then, create the CLI. cli := humacli.New(func(hooks humacli.Hooks, opts *Options) { fmt.Printf("I was run with debug:%v host:%v port%v\n", opts.Debug, opts.Host, opts.Port) }) // Run the thing! cli.Run() } ``` -------------------------------- ### Go Client for Generated SDK Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/client-sdks.md This Go client script demonstrates how to use a generated SDK to interact with an API. It initializes the SDK client, makes a request to the 'GetGreeting' endpoint, and handles potential errors or non-200 status codes. The client assumes the SDK was generated into the 'sdk' package. ```go package main import ( "context" "fmt" "github.com/my-user/my-api/sdk" ) func main() { ctx := context.Background() // Initialize an SDK client. client, _ := sdk.NewClientWithResponses("http://localhost:8888") // Make the greeting request. greeting, err := client.GetGreetingWithResponse(ctx, "world") if err != nil { panic(err) } if greeting.StatusCode() > 200 { panic(greeting.ApplicationProblemJSONDefault) } // Everything was successful, so print the message. fmt.Println(greeting.JSON200.Message) } ``` -------------------------------- ### Initialize Huma API with Chi Router Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/bring-your-own-router.md This Go code snippet shows how to initialize Huma with the Chi router. It involves creating a Chi router instance, wrapping it with `humachi.New`, and providing a Huma configuration. This enables Huma's features to be used with the Chi routing framework. ```go import ( "github.com/danielgtaylor/huma/v2" "github.com/danielgtaylor/huma/v2/adapters/humachi" "github.com/go-chi/chi/v5" ) // Create your router. router := chi.NewMux() // Wrap the router with Huma to create an API instance. api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0")) // Register your operations with the API. // ... // Start the server! http.ListenAndServe(":8888", r) ``` -------------------------------- ### Create a Test API Instance with Huma Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/test-utilities.md Demonstrates the initial step of creating a router-agnostic test API instance using `humatest.New`. This instance is used to register routes and make requests for testing purposes. ```go import ( t"testing" "github.com/danielgtaylor/huma/v2/humatest" ) func TestMyAPI(t *testing.T) { router, api := humatest.New(t) } ``` -------------------------------- ### Configure SwaggerUI Renderer Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/api-docs.md Enable SwaggerUI by setting `config.DocsRenderer` to `huma.DocsRendererSwaggerUI`. Further customize its behavior using `config.DocsRendererConfig`, such as controlling model expansion depth and enabling the 'Try it out' feature. ```go router := chi.NewRouter() config := huma.DefaultConfig("Docs Example", "1.0.0") config.DocsRenderer = huma.DocsRendererSwaggerUI // Optional. These fields are merged into the SwaggerUIBundle config object. See // https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ config.DocsRendererConfig = map[string]any{ "defaultModelsExpandDepth": -1, // hide the models section "tryItOutEnabled": true, // enable "Try it out" by default } api := humachi.New(router, config) ``` -------------------------------- ### Configure OpenAPI for Client Auto-Configuration Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/how-to/oauth2-jwt.md Add the `x-cli-config` extension to your OpenAPI document to enable client auto-configuration. This allows clients like Restish to automatically configure themselves for authentication. ```go config.Extensions["x-cli-config"] = huma.AutoConfig{ /* ... */ } ``` -------------------------------- ### Configure App Name and Version Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/cli.md Shows how to set the application name and version metadata by modifying the root Cobra command fields. These values are automatically reflected in the CLI help output and version flag. ```go cmd := cli.Root() cmd.Use = "appname" cmd.Version = "1.0.1" cli.Run() ``` -------------------------------- ### GET /greeting/{name} Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/tutorial/sending-data.md Retrieves a personalized greeting for a specified name. ```APIDOC ## GET /greeting/{name} ### Description Returns a greeting message for the person provided in the path parameter. ### Method GET ### Endpoint /greeting/{name} ### Parameters #### Path Parameters - **name** (string) - Required - Name to greet (max 30 chars) ### Response #### Success Response (200) - **message** (string) - The greeting message #### Response Example { "message": "Hello, world!" } ``` -------------------------------- ### Create and Register Huma API Groups Source: https://github.com/danielgtaylor/huma/blob/main/docs/docs/features/groups.md Demonstrates how to initialize a new API group with a path prefix, apply middleware, and register operations within that group. ```go grp := huma.NewGroup(api, "/v1") grp.UseMiddleware(authMiddleware) huma.Get(grp, "/users", func(ctx context.Context, input *struct{}) (*UsersResponse, error) { // ... }) ```