[{"data":1,"prerenderedAt":557},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fmain\u002Fhttp":3},{"id":4,"title":5,"body":6,"description":544,"extension":545,"group":546,"meta":547,"navigation":548,"order":549,"path":550,"section":551,"seo":552,"source":553,"stem":554,"version":555,"__hash__":556},"docs\u002Fdocs\u002Fmain\u002Fhttp.md","HTTP and OpenAPI",{"type":7,"value":8,"toc":534},"minimark",[9,14,18,230,249,281,309,318,325,329,365,436,440,450,454,461,465,487,491,494,498,514,518,530],[10,11,13],"h2",{"id":12},"register-typed-endpoints","Register typed endpoints",[15,16,17],"p",{},"Declare routes together and pass typed handler methods directly. Request and response types are inferred from each handler:",[19,20,25],"pre",{"className":21,"code":22,"language":23,"meta":24,"style":24},"language-go shiki shiki-themes light-plus light-plus dark-plus","func Register(r transport.EndpointRegistrar, actions Actions) error {\n    h := Handler{Actions: actions}\n    return transport.Routes(r,\n        transport.Post(\"\u002Fusers\", h.Create).Name(\"createUser\").Errors(409),\n        transport.Get(\"\u002Fusers\u002F:id\", h.Get).Name(\"getUser\").Errors(404),\n    )\n}\n","go","",[26,27,28,77,103,124,176,219,225],"code",{"__ignoreMap":24},[29,30,33,37,41,45,49,53,56,59,62,65,68,71,74],"span",{"class":31,"line":32},"line",1,[29,34,36],{"class":35},"stxUP","func",[29,38,40],{"class":39},"swoLU"," Register",[29,42,44],{"class":43},"s_Yst","(",[29,46,48],{"class":47},"sswaR","r",[29,50,52],{"class":51},"sopvc"," transport",[29,54,55],{"class":43},".",[29,57,58],{"class":51},"EndpointRegistrar",[29,60,61],{"class":43},", ",[29,63,64],{"class":47},"actions",[29,66,67],{"class":51}," Actions",[29,69,70],{"class":43},") ",[29,72,73],{"class":51},"error",[29,75,76],{"class":43}," {\n",[29,78,80,83,86,89,92,95,98,100],{"class":31,"line":79},2,[29,81,82],{"class":47},"    h",[29,84,85],{"class":43}," := ",[29,87,88],{"class":51},"Handler",[29,90,91],{"class":43},"{",[29,93,94],{"class":47},"Actions",[29,96,97],{"class":43},": ",[29,99,64],{"class":47},[29,101,102],{"class":43},"}\n",[29,104,106,110,112,114,117,119,121],{"class":31,"line":105},3,[29,107,109],{"class":108},"smUd-","    return",[29,111,52],{"class":47},[29,113,55],{"class":43},[29,115,116],{"class":39},"Routes",[29,118,44],{"class":43},[29,120,48],{"class":47},[29,122,123],{"class":43},",\n",[29,125,127,130,132,135,137,141,143,146,148,151,154,157,159,162,164,167,169,173],{"class":31,"line":126},4,[29,128,129],{"class":47},"        transport",[29,131,55],{"class":43},[29,133,134],{"class":39},"Post",[29,136,44],{"class":43},[29,138,140],{"class":139},"sFD8J","\"\u002Fusers\"",[29,142,61],{"class":43},[29,144,145],{"class":47},"h",[29,147,55],{"class":43},[29,149,150],{"class":47},"Create",[29,152,153],{"class":43},").",[29,155,156],{"class":39},"Name",[29,158,44],{"class":43},[29,160,161],{"class":139},"\"createUser\"",[29,163,153],{"class":43},[29,165,166],{"class":39},"Errors",[29,168,44],{"class":43},[29,170,172],{"class":171},"s-S-M","409",[29,174,175],{"class":43},"),\n",[29,177,179,181,183,186,188,191,193,195,197,199,201,203,205,208,210,212,214,217],{"class":31,"line":178},5,[29,180,129],{"class":47},[29,182,55],{"class":43},[29,184,185],{"class":39},"Get",[29,187,44],{"class":43},[29,189,190],{"class":139},"\"\u002Fusers\u002F:id\"",[29,192,61],{"class":43},[29,194,145],{"class":47},[29,196,55],{"class":43},[29,198,185],{"class":47},[29,200,153],{"class":43},[29,202,156],{"class":39},[29,204,44],{"class":43},[29,206,207],{"class":139},"\"getUser\"",[29,209,153],{"class":43},[29,211,166],{"class":39},[29,213,44],{"class":43},[29,215,216],{"class":171},"404",[29,218,175],{"class":43},[29,220,222],{"class":31,"line":221},6,[29,223,224],{"class":43},"    )\n",[29,226,228],{"class":31,"line":227},7,[29,229,102],{"class":43},[15,231,232,233,236,237,240,241,244,245,248],{},"Import ",[26,234,235],{},"transport \"github.com\u002Famkargar\u002Fgonex\u002Fhttp\"",". A handler has the signature ",[26,238,239],{},"func(context.Context, Request) (Response, error)","; named structs in ",[26,242,243],{},"schemas.go"," declare the contract. Give every route a unique ",[26,246,247],{},".Name(...)"," for its OpenAPI operation ID.",[15,250,251,61,253,61,256,61,259,262,263,266,267,269,270,273,274,277,278,55],{},[26,252,185],{},[26,254,255],{},"Put",[26,257,258],{},"Patch",[26,260,261],{},"Head"," and ",[26,264,265],{},"Options"," default to 200; ",[26,268,134],{}," defaults to 201 and ",[26,271,272],{},"Delete"," to 204. Override with ",[26,275,276],{},".Status(...)",". A 204 endpoint should return ",[26,279,280],{},"NoBody",[15,282,283,284,61,287,61,290,61,293,61,296,61,299,61,302,262,305,308],{},"Optional metadata stays next to the route: ",[26,285,286],{},".Summary(...)",[26,288,289],{},".Description(...)",[26,291,292],{},".Tags(...)",[26,294,295],{},".Errors(...)",[26,297,298],{},".Use(...)",[26,300,301],{},".Security(requirements, schemes)",[26,303,304],{},".MaxBodyBytes(...)",[26,306,307],{},".Examples(request, response)",". Middleware runs before binding and validation. Versioned registrars work with the same route declarations.",[15,310,311,313,314,317],{},[26,312,116],{}," uses the existing typed registration pipeline: validation, binding, request limits, error mapping and OpenAPI remain identical. Return its error from ",[26,315,316],{},"Module.Register","; the application commits module registration only after all modules succeed. Reusing a declaration to register multiple paths is discouraged; define each route once during startup.",[15,319,320,321,324],{},"The lower-level ",[26,322,323],{},"http.Register(registrar, http.Endpoint[Request, Response]{...})"," API remains supported for existing applications. Business services return plain Go values; adapters map those into transport schemas.",[10,326,328],{"id":327},"bind-and-validate-requests","Bind and validate requests",[15,330,331,332,61,335,61,338,341,342,345,346,349,350,353,354,357,358,361,362,364],{},"Each request wrapper field declares exactly one origin: ",[26,333,334],{},"path:\"id\"",[26,336,337],{},"query:\"page\"",[26,339,340],{},"header:\"X-Token\""," or ",[26,343,344],{},"body:\"true\"",". There may be only one body field. Parameters are scalar or pointers to scalars. Path placeholders must match field bindings. Body schemas use standard ",[26,347,348],{},"json"," tags and ",[26,351,352],{},"validate"," tags. Required, min\u002Fmax, email, nested structs and slice ",[26,355,356],{},"dive"," validation are supported. Use pointers to distinguish absent numeric\u002Fboolean values from zero\u002Ffalse; ",[26,359,360],{},"required"," on a pointer requires presence, while ",[26,363,360],{}," on a scalar rejects its zero value.",[366,367,368,384],"table",{},[369,370,371],"thead",{},[372,373,374,378,381],"tr",{},[375,376,377],"th",{},"Origin",[375,379,380],{},"Example tag",[375,382,383],{},"Constraint",[385,386,387,400,412,424],"tbody",{},[372,388,389,393,397],{},[390,391,392],"td",{},"Path",[390,394,395],{},[26,396,334],{},[390,398,399],{},"Required; must match the route placeholder",[372,401,402,405,409],{},[390,403,404],{},"Query",[390,406,407],{},[26,408,337],{},[390,410,411],{},"Scalar or pointer to a scalar",[372,413,414,417,421],{},[390,415,416],{},"Header",[390,418,419],{},[26,420,340],{},[390,422,423],{},"Scalar or pointer; duplicates are rejected",[372,425,426,429,433],{},[390,427,428],{},"Body",[390,430,431],{},[26,432,344],{},[390,434,435],{},"One JSON body field per request wrapper",[10,437,439],{"id":438},"handle-failures-and-limits","Handle failures and limits",[15,441,442,443,446,447,449],{},"Malformed JSON, missing required parameters and unsupported content types return 400. Unknown or incorrectly cased JSON fields, duplicate object keys, trailing values, duplicate query\u002Fheader values and null nonnullable bodies are rejected. Validation failures return 422 with field paths and codes. Request bodies default to 1 MiB; set ",[26,444,445],{},"MaxBodyBytes"," per endpoint. Application errors must be declared in ",[26,448,166],{}," to expose their mapped status\u002Fmessage; undeclared\u002Finternal errors return a redacted 500. Context deadline failures return a documented 504. 204 responses have no body.",[10,451,453],{"id":452},"describe-endpoint-metadata","Describe endpoint metadata",[15,455,456,457,460],{},"Optional summary, description, tags, request\u002Fresponse examples, security requirements\u002Fschemes and middleware live on the same endpoint contract. Middleware must return documented response shapes\u002Fstatuses. Low-level ",[26,458,459],{},"Registrar.Handle"," is an escape hatch for raw Gin routes and is not projected into OpenAPI; public application endpoints should use typed registration.",[10,462,464],{"id":463},"serve-and-export-documents","Serve and export documents",[15,466,467,470,471,474,475,478,479,482,483,486],{},[26,468,469],{},"\u002Fopenapi.json"," is enabled by default; ",[26,472,473],{},"DisableOpenAPI"," removes it in production. ",[26,476,477],{},"\u002Fdocs"," is an opt-in local document link (",[26,480,481],{},"DocsEnabled","), without externally loaded assets. Runtime-owned paths reject conflicts. The specification is built and validated once during startup, not per request. ",[26,484,485],{},"App.OpenAPI()"," explicitly exports without starting a listener.",[10,488,490],{"id":489},"supported-dto-schemas","Supported DTO schemas",[15,492,493],{},"Schemas support named\u002Fnested\u002Frecursive structs, pointers\u002Fnullability, string-keyed maps and slices; component names include a stable package hash. Input requiredness follows validation, output requiredness follows JSON omission. Nested input objects require pointers (except time.Time) so presence has an explicit representation. A value body wrapper is already required: omit its redundant required validation tag. Anonymous embedded fields, byte slices, non-string map keys, custom JSON encodings and unsupported JSON tag options require explicit DTOs. Supported validation tags are required, omitempty, min, max, email, dive and -; unsupported or contradictory constraints fail registration. The official OpenAPI Initiative 3.1 schema is vendored with its source URL; santhosh-tekuri\u002Fjsonschema v6 validates generated documents offline.",[10,495,497],{"id":496},"freeze-and-compare-contracts","Freeze and compare contracts",[15,499,500,501,504,505,508,509,55],{},"Contracts and handler slices are detached from caller-owned metadata at registration. Security requirements must reference declared schemes. Export a version with ",[26,502,503],{},"gonex openapi generate --http-version v1 --out v1.json","; compare it with a released baseline using ",[26,506,507],{},"gonex openapi validate --file v1.json --against baseline.json",". Compatibility checking is conservative; see ",[510,511,513],"a",{"href":512},"\u002Fdocs\u002Fmain\u002Fupgrades\u002F","upgrade policy",[10,515,517],{"id":516},"browser-diagnostics","Browser diagnostics",[15,519,520,521,524,525,529],{},"With ",[26,522,523],{},"DEBUG=true",", requests accepting HTML receive a development error page for uncommitted error responses. JSON clients retain their typed API contracts. See ",[510,526,528],{"href":527},"\u002Fdocs\u002Fmain\u002Fdebug\u002F","debug mode"," for the welcome page, exception details and production settings.",[531,532,533],"style",{},"html pre.shiki code .stxUP, html code.shiki .stxUP{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#569CD6}html pre.shiki code .swoLU, html code.shiki .swoLU{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .s_Yst, html code.shiki .s_Yst{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#D4D4D4}html pre.shiki code .sswaR, html code.shiki .sswaR{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#9CDCFE}html pre.shiki code .sopvc, html code.shiki .sopvc{--shiki-light:#267F99;--shiki-default:#267F99;--shiki-dark:#4EC9B0}html pre.shiki code .smUd-, html code.shiki .smUd-{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#C586C0}html pre.shiki code .sFD8J, html code.shiki .sFD8J{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#CE9178}html pre.shiki code .s-S-M, html code.shiki .s-S-M{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#B5CEA8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":24,"searchDepth":79,"depth":79,"links":535},[536,537,538,539,540,541,542,543],{"id":12,"depth":79,"text":13},{"id":327,"depth":79,"text":328},{"id":438,"depth":79,"text":439},{"id":452,"depth":79,"text":453},{"id":463,"depth":79,"text":464},{"id":489,"depth":79,"text":490},{"id":496,"depth":79,"text":497},{"id":516,"depth":79,"text":517},"Build typed HTTP endpoints with Gin adapters, request validation and OpenAPI 3.1 contracts in Gonex.","md","APPLICATION DESIGN",{},true,90,"\u002Fdocs\u002Fmain\u002Fhttp","build",{"title":5,"description":544},"http-openapi.md","docs\u002Fmain\u002Fhttp","main","p0b8px_2t638EDrRoPWM90rUI8tw_8vAwdgukMXGEbo",1792521640356]