MCPcopy
hub / github.com/danielgtaylor/huma / Register

Function Register

huma.go:711–1167  ·  view source on GitHub ↗

Register an operation handler for an API. The handler must be a function that takes a context and a pointer to the input struct and returns a pointer to the output struct and an error. The input struct must be a struct with fields for the request path/query/header/cookie parameters and/or body. The

(api API, op Operation, handler func(context.Context, *I) (*O, error))

Source from the content-addressed store, hash-verified

709// return resp, nil
710// })
711func Register[I, O any](api API, op Operation, handler func(context.Context, *I) (*O, error)) {
712 oapi := api.OpenAPI()
713 registry := oapi.Components.Schemas
714
715 if op.Method == "" {
716 panic("method must be specified in operation")
717 }
718 if op.Path == "" {
719 if grp, ok := api.(*Group); !ok || len(grp.prefixes) == 0 {
720 panic("path must be specified in operation")
721 }
722 }
723 initResponses(&op)
724
725 inputType := reflect.TypeFor[I]()
726 if inputType.Kind() != reflect.Struct {
727 panic("input must be a struct")
728 }
729 inputParams, inputBodyIndex, hasInputBody, rawBodyIndex, rbt, rawBodyDataT, inSchema := processInputType(inputType, &op, registry)
730
731 outputType := reflect.TypeFor[O]()
732 if outputType.Kind() != reflect.Struct {
733 panic("output must be a struct")
734 }
735 outHeaders, outStatusIndex, outBodyIndex, outBodyFunc := processOutputType(outputType, &op, registry)
736
737 if len(op.Errors) > 0 {
738 if len(inputParams.Paths) > 0 || hasInputBody {
739 op.Errors = append(op.Errors, http.StatusUnprocessableEntity)
740 }
741 op.Errors = append(op.Errors, http.StatusInternalServerError)
742 }
743 defineErrors(&op, registry)
744
745 if documenter, ok := api.(OperationDocumenter); ok {
746 // Enables customization of OpenAPI documentation behavior for operations.
747 documenter.DocumentOperation(&op)
748 } else if !op.Hidden {
749 oapi.AddOperation(&op)
750 }
751
752 resolvers := findResolvers(resolverType, inputType)
753 defaults := findDefaults(registry, inputType)
754
755 // Pre-compute query parameter validation data to reduce per-request allocations.
756 knownParams := make(map[string]struct{})
757 var deepPrefixes []string
758 for i := range inputParams.Paths {
759 p := inputParams.Paths[i].Value
760 if p == nil || p.Loc != "query" {
761 continue
762 }
763
764 if p.Style == styleDeepObject {
765 deepPrefixes = append(deepPrefixes, p.Name+"[")
766 continue
767 }
768

Callers 1

convenienceFunction · 0.70

Calls 15

GetStatusMethod · 0.95
GetHeadersMethod · 0.95
initResponsesFunction · 0.85
processInputTypeFunction · 0.85
processOutputTypeFunction · 0.85
defineErrorsFunction · 0.85
findResolversFunction · 0.85
findDefaultsFunction · 0.85
findParamsFunction · 0.85
writeErrFunction · 0.85
ReadCookiesFunction · 0.85
parseDeepObjectQueryFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…