[{"data":1,"prerenderedAt":1530},["ShallowReactive",2],{"navigation_docs":3,"-core-request-binding":172,"-core-request-binding-surround":1525},[4,26,67,98,124,140,161],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting Started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Core","i-lucide-box","\u002Fcore","2.core",[32,37,42,47,52,57,62],{"title":33,"path":34,"stem":35,"icon":36},"Routing","\u002Fcore\u002Frouting","2.core\u002F1.routing","i-lucide-route",{"title":38,"path":39,"stem":40,"icon":41},"Handlers","\u002Fcore\u002Fhandlers","2.core\u002F2.handlers","i-lucide-braces",{"title":43,"path":44,"stem":45,"icon":46},"Request Binding","\u002Fcore\u002Frequest-binding","2.core\u002F3.request-binding","i-lucide-tags",{"title":48,"path":49,"stem":50,"icon":51},"Validation","\u002Fcore\u002Fvalidation","2.core\u002F4.validation","i-lucide-check-check",{"title":53,"path":54,"stem":55,"icon":56},"Context","\u002Fcore\u002Fcontext","2.core\u002F5.context","i-lucide-file-input",{"title":58,"path":59,"stem":60,"icon":61},"Errors","\u002Fcore\u002Ferrors","2.core\u002F6.errors","i-lucide-triangle-alert",{"title":63,"path":64,"stem":65,"icon":66},"Middleware","\u002Fcore\u002Fmiddleware","2.core\u002F7.middleware","i-lucide-layers",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":25},"Auth","i-lucide-shield-check","\u002Fauth","3.auth",[73,78,83,88,93],{"title":74,"path":75,"stem":76,"icon":77},"Overview","\u002Fauth\u002Foverview","3.auth\u002F1.overview","i-lucide-shield",{"title":79,"path":80,"stem":81,"icon":82},"Auth Rules","\u002Fauth\u002Fauth-rules","3.auth\u002F2.auth-rules","i-lucide-lock",{"title":84,"path":85,"stem":86,"icon":87},"JWT Providers","\u002Fauth\u002Fjwt-providers","3.auth\u002F3.jwt-providers","i-lucide-key",{"title":89,"path":90,"stem":91,"icon":92},"Roles & Permissions","\u002Fauth\u002Froles-and-permissions","3.auth\u002F4.roles-and-permissions","i-lucide-users",{"title":94,"path":95,"stem":96,"icon":97},"Audit Logging","\u002Fauth\u002Faudit-logging","3.auth\u002F5.audit-logging","i-lucide-scroll-text",{"title":99,"icon":100,"path":101,"stem":102,"children":103,"page":25},"GoTrue","i-lucide-key-round","\u002Fgotrue","4.gotrue",[104,109,114,119],{"title":105,"path":106,"stem":107,"icon":108},"Proxy","\u002Fgotrue\u002Fproxy","4.gotrue\u002F1.proxy","i-lucide-shuffle",{"title":110,"path":111,"stem":112,"icon":113},"Endpoints","\u002Fgotrue\u002Fendpoints","4.gotrue\u002F2.endpoints","i-lucide-list",{"title":115,"path":116,"stem":117,"icon":118},"Client IP & Rate Limits","\u002Fgotrue\u002Fclient-ip-and-rate-limits","4.gotrue\u002F3.client-ip-and-rate-limits","i-lucide-network",{"title":120,"path":121,"stem":122,"icon":123},"Deployment","\u002Fgotrue\u002Fdeployment","4.gotrue\u002F4.deployment","i-lucide-server",{"title":125,"icon":126,"path":127,"stem":128,"children":129,"page":25},"API Docs","i-lucide-file-text","\u002Fapi-docs","5.api-docs",[130,135],{"title":131,"path":132,"stem":133,"icon":134},"OpenAPI","\u002Fapi-docs\u002Fopenapi","5.api-docs\u002F1.openapi","i-lucide-file-json",{"title":136,"path":137,"stem":138,"icon":139},"Scalar UI","\u002Fapi-docs\u002Fscalar","5.api-docs\u002F2.scalar","i-lucide-book-open-text",{"title":141,"icon":142,"path":143,"stem":144,"children":145,"page":25},"Guides","i-lucide-compass","\u002Fguides","6.guides",[146,151,156],{"title":147,"path":148,"stem":149,"icon":150},"Testing","\u002Fguides\u002Ftesting","6.guides\u002F1.testing","i-lucide-flask-conical",{"title":152,"path":153,"stem":154,"icon":155},"Performance","\u002Fguides\u002Fperformance","6.guides\u002F2.performance","i-lucide-gauge",{"title":157,"path":158,"stem":159,"icon":160},"Releasing","\u002Fguides\u002Freleasing","6.guides\u002F3.releasing","i-lucide-tag",{"title":162,"icon":163,"path":164,"stem":165,"children":166,"page":25},"Reference","i-lucide-code","\u002Freference","7.reference",[167],{"title":168,"path":169,"stem":170,"icon":171},"API Reference","\u002Freference\u002Fapi-reference","7.reference\u002F1.api-reference","i-lucide-list-tree",{"id":173,"title":43,"body":174,"description":1518,"extension":1519,"links":1520,"meta":1521,"navigation":1522,"path":44,"seo":1523,"stem":45,"__hash__":1524},"docs\u002F2.core\u002F3.request-binding.md",{"type":175,"value":176,"toc":1507},"minimark",[177,181,335,340,460,463,467,470,499,502,569,576,580,593,674,681,688,757,761,769,831,834,838,841,892,914,925,929,932,972,1001,1068,1075,1079,1258,1274,1278,1285,1408,1482,1485,1489,1503],[178,179,180],"p",{},"Binding is driven by struct tags. Declare where each field comes from and ezz fills it in before your handler runs.",[182,183,188],"pre",{"className":184,"code":185,"language":186,"meta":187,"style":187},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","type SearchRequest struct {\n    Team    string   `path:\"team\"`\n    Query   string   `query:\"q\"`\n    Tags    []string `query:\"tags\"`\n    Page    int      `query:\"page\" default:\"1\"`\n    Limit   int      `query:\"limit\" default:\"25\"`\n    TraceID string   `header:\"X-Trace-ID\"`\n    Filters Filters  `json:\"filters\"`\n}\n","go","",[189,190,191,210,231,246,265,282,297,312,329],"code",{"__ignoreMap":187},[192,193,196,200,204,207],"span",{"class":194,"line":195},"line",1,[192,197,199],{"class":198},"sMK4o","type",[192,201,203],{"class":202},"sBMFI"," SearchRequest",[192,205,206],{"class":198}," struct",[192,208,209],{"class":198}," {\n",[192,211,213,217,221,224,228],{"class":194,"line":212},2,[192,214,216],{"class":215},"sTEyZ","    Team    ",[192,218,220],{"class":219},"spNyl","string",[192,222,223],{"class":198},"   `",[192,225,227],{"class":226},"sfazB","path:\"team\"",[192,229,230],{"class":198},"`\n",[192,232,234,237,239,241,244],{"class":194,"line":233},3,[192,235,236],{"class":215},"    Query   ",[192,238,220],{"class":219},[192,240,223],{"class":198},[192,242,243],{"class":226},"query:\"q\"",[192,245,230],{"class":198},[192,247,249,252,255,257,260,263],{"class":194,"line":248},4,[192,250,251],{"class":215},"    Tags    ",[192,253,254],{"class":198},"[]",[192,256,220],{"class":219},[192,258,259],{"class":198}," `",[192,261,262],{"class":226},"query:\"tags\"",[192,264,230],{"class":198},[192,266,268,271,274,277,280],{"class":194,"line":267},5,[192,269,270],{"class":215},"    Page    ",[192,272,273],{"class":219},"int",[192,275,276],{"class":198},"      `",[192,278,279],{"class":226},"query:\"page\" default:\"1\"",[192,281,230],{"class":198},[192,283,285,288,290,292,295],{"class":194,"line":284},6,[192,286,287],{"class":215},"    Limit   ",[192,289,273],{"class":219},[192,291,276],{"class":198},[192,293,294],{"class":226},"query:\"limit\" default:\"25\"",[192,296,230],{"class":198},[192,298,300,303,305,307,310],{"class":194,"line":299},7,[192,301,302],{"class":215},"    TraceID ",[192,304,220],{"class":219},[192,306,223],{"class":198},[192,308,309],{"class":226},"header:\"X-Trace-ID\"",[192,311,230],{"class":198},[192,313,315,318,321,324,327],{"class":194,"line":314},8,[192,316,317],{"class":215},"    Filters ",[192,319,320],{"class":202},"Filters",[192,322,323],{"class":198},"  `",[192,325,326],{"class":226},"json:\"filters\"",[192,328,230],{"class":198},[192,330,332],{"class":194,"line":331},9,[192,333,334],{"class":198},"}\n",[336,337,339],"h2",{"id":338},"choose-a-source","Choose a source",[341,342,343,359],"table",{},[344,345,346],"thead",{},[347,348,349,353,356],"tr",{},[350,351,352],"th",{},"Tag",[350,354,355],{},"Reads from",[350,357,358],{},"Example",[360,361,362,382,397,412,430,445],"tbody",{},[347,363,364,370,377],{},[365,366,367],"td",{},[189,368,369],{},"path",[365,371,372,373,376],{},"A ",[189,374,375],{},"{name}"," segment of the route pattern",[365,378,379],{},[189,380,381],{},"`path:\"id\"`",[347,383,384,389,392],{},[365,385,386],{},[189,387,388],{},"query",[365,390,391],{},"The query string",[365,393,394],{},[189,395,396],{},"`query:\"page\"`",[347,398,399,404,407],{},[365,400,401],{},[189,402,403],{},"header",[365,405,406],{},"A request header",[365,408,409],{},[189,410,411],{},"`header:\"X-Api-Version\"`",[347,413,414,419,425],{},[365,415,416],{},[189,417,418],{},"form",[365,420,421,422],{},"Form values, via ",[189,423,424],{},"ParseForm",[365,426,427],{},[189,428,429],{},"`form:\"email\"`",[347,431,432,437,440],{},[365,433,434],{},[189,435,436],{},"json",[365,438,439],{},"The JSON request body",[365,441,442],{},[189,443,444],{},"`json:\"name\"`",[347,446,447,452,455],{},[365,448,449],{},[189,450,451],{},"default",[365,453,454],{},"A fallback for missing query parameters",[365,456,457],{},[189,458,459],{},"`query:\"page\" default:\"1\"`",[178,461,462],{},"A field can carry more than one tag. Fields without any of these tags are left at their zero value unless they appear in the JSON body.",[336,464,466],{"id":465},"understand-the-binding-order","Understand the binding order",[178,468,469],{},"Binding happens in two passes:",[471,472,473,485],"ol",{},[474,475,476,477,480,481,484],"li",{},"If the request has a ",[189,478,479],{},"Content-Type"," containing ",[189,482,483],{},"application\u002Fjson",", the body is decoded into the whole struct.",[474,486,487,488,490,491,490,493,495,496,498],{},"Then ",[189,489,369],{},", ",[189,492,388],{},[189,494,403],{},", and ",[189,497,418],{}," values are applied field by field.",[178,500,501],{},"Because the second pass runs last, a request value overwrites whatever the body set for the same field. That is useful for canonicalising an ID:",[182,503,505],{"className":184,"code":504,"language":186,"meta":187,"style":187},"type UpdateUserRequest struct {\n    ID    string `path:\"id\"`               \u002F\u002F always wins\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\n",[189,506,507,518,537,551,565],{"__ignoreMap":187},[192,508,509,511,514,516],{"class":194,"line":195},[192,510,199],{"class":198},[192,512,513],{"class":202}," UpdateUserRequest",[192,515,206],{"class":198},[192,517,209],{"class":198},[192,519,520,523,525,527,530,533],{"class":194,"line":212},[192,521,522],{"class":215},"    ID    ",[192,524,220],{"class":219},[192,526,259],{"class":198},[192,528,529],{"class":226},"path:\"id\"",[192,531,532],{"class":198},"`",[192,534,536],{"class":535},"sHwdD","               \u002F\u002F always wins\n",[192,538,539,542,544,546,549],{"class":194,"line":233},[192,540,541],{"class":215},"    Name  ",[192,543,220],{"class":219},[192,545,259],{"class":198},[192,547,548],{"class":226},"json:\"name\"",[192,550,230],{"class":198},[192,552,553,556,558,560,563],{"class":194,"line":248},[192,554,555],{"class":215},"    Email ",[192,557,220],{"class":219},[192,559,259],{"class":198},[192,561,562],{"class":226},"json:\"email\"",[192,564,230],{"class":198},[192,566,567],{"class":194,"line":267},[192,568,334],{"class":198},[178,570,571,572,575],{},"A body field is only overwritten when the corresponding request value is present and non-empty, so ",[189,573,574],{},"?name="," does not blank out a name that came from the body.",[336,577,579],{"id":578},"decode-json-bodies","Decode JSON bodies",[178,581,582,583,585,586,588,589,592],{},"The body is decoded when the ",[189,584,479],{}," header contains ",[189,587,483],{}," and the request either declares a length or uses chunked encoding. An empty body is not an error, so ",[189,590,591],{},"POST"," with no body binds nothing and validation decides whether that is acceptable.",[182,594,596],{"className":184,"code":595,"language":186,"meta":187,"style":187},"type CreateUserRequest struct {\n    Name    string   `json:\"name\" validate:\"required\"`\n    Email   string   `json:\"email\" validate:\"required,email\"`\n    Tags    []string `json:\"tags\"`\n    Profile *Profile `json:\"profile\"`\n}\n",[189,597,598,609,623,637,652,670],{"__ignoreMap":187},[192,599,600,602,605,607],{"class":194,"line":195},[192,601,199],{"class":198},[192,603,604],{"class":202}," CreateUserRequest",[192,606,206],{"class":198},[192,608,209],{"class":198},[192,610,611,614,616,618,621],{"class":194,"line":212},[192,612,613],{"class":215},"    Name    ",[192,615,220],{"class":219},[192,617,223],{"class":198},[192,619,620],{"class":226},"json:\"name\" validate:\"required\"",[192,622,230],{"class":198},[192,624,625,628,630,632,635],{"class":194,"line":233},[192,626,627],{"class":215},"    Email   ",[192,629,220],{"class":219},[192,631,223],{"class":198},[192,633,634],{"class":226},"json:\"email\" validate:\"required,email\"",[192,636,230],{"class":198},[192,638,639,641,643,645,647,650],{"class":194,"line":248},[192,640,251],{"class":215},[192,642,254],{"class":198},[192,644,220],{"class":219},[192,646,259],{"class":198},[192,648,649],{"class":226},"json:\"tags\"",[192,651,230],{"class":198},[192,653,654,657,660,663,665,668],{"class":194,"line":267},[192,655,656],{"class":215},"    Profile ",[192,658,659],{"class":198},"*",[192,661,662],{"class":202},"Profile",[192,664,259],{"class":198},[192,666,667],{"class":226},"json:\"profile\"",[192,669,230],{"class":198},[192,671,672],{"class":194,"line":284},[192,673,334],{"class":198},[178,675,676,677,680],{},"Nested structs, slices, maps, and pointers all work, because this pass is ",[189,678,679],{},"encoding\u002Fjson",".",[178,682,683,684,687],{},"A malformed body returns ",[189,685,686],{},"400"," with a message describing the decode failure:",[182,689,692],{"className":690,"code":691,"language":436,"meta":187,"style":187},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"error\": true,\n  \"message\": \"failed to decode JSON body: invalid character 'x' looking for beginning of value\",\n  \"status\": 400\n}\n",[189,693,694,699,716,738,753],{"__ignoreMap":187},[192,695,696],{"class":194,"line":195},[192,697,698],{"class":198},"{\n",[192,700,701,704,707,710,713],{"class":194,"line":212},[192,702,703],{"class":198},"  \"",[192,705,706],{"class":219},"error",[192,708,709],{"class":198},"\"",[192,711,712],{"class":198},":",[192,714,715],{"class":198}," true,\n",[192,717,718,720,723,725,727,730,733,735],{"class":194,"line":233},[192,719,703],{"class":198},[192,721,722],{"class":219},"message",[192,724,709],{"class":198},[192,726,712],{"class":198},[192,728,729],{"class":198}," \"",[192,731,732],{"class":226},"failed to decode JSON body: invalid character 'x' looking for beginning of value",[192,734,709],{"class":198},[192,736,737],{"class":198},",\n",[192,739,740,742,745,747,749],{"class":194,"line":248},[192,741,703],{"class":198},[192,743,744],{"class":219},"status",[192,746,709],{"class":198},[192,748,712],{"class":198},[192,750,752],{"class":751},"sbssI"," 400\n",[192,754,755],{"class":194,"line":267},[192,756,334],{"class":198},[336,758,760],{"id":759},"supply-defaults","Supply defaults",[178,762,763,765,766,768],{},[189,764,451],{}," applies to ",[189,767,388],{}," fields whose parameter is absent or empty. It is not consulted for path, header, form, or body values.",[182,770,772],{"className":184,"code":771,"language":186,"meta":187,"style":187},"type ListRequest struct {\n    Page  int    `query:\"page\" default:\"1\"`\n    Limit int    `query:\"limit\" default:\"25\" validate:\"min=1,max=100\"`\n    Sort  string `query:\"sort\" default:\"created_at\"`\n}\n",[189,773,774,785,799,813,827],{"__ignoreMap":187},[192,775,776,778,781,783],{"class":194,"line":195},[192,777,199],{"class":198},[192,779,780],{"class":202}," ListRequest",[192,782,206],{"class":198},[192,784,209],{"class":198},[192,786,787,790,792,795,797],{"class":194,"line":212},[192,788,789],{"class":215},"    Page  ",[192,791,273],{"class":219},[192,793,794],{"class":198},"    `",[192,796,279],{"class":226},[192,798,230],{"class":198},[192,800,801,804,806,808,811],{"class":194,"line":233},[192,802,803],{"class":215},"    Limit ",[192,805,273],{"class":219},[192,807,794],{"class":198},[192,809,810],{"class":226},"query:\"limit\" default:\"25\" validate:\"min=1,max=100\"",[192,812,230],{"class":198},[192,814,815,818,820,822,825],{"class":194,"line":248},[192,816,817],{"class":215},"    Sort  ",[192,819,220],{"class":219},[192,821,259],{"class":198},[192,823,824],{"class":226},"query:\"sort\" default:\"created_at\"",[192,826,230],{"class":198},[192,828,829],{"class":194,"line":267},[192,830,334],{"class":198},[178,832,833],{},"Defaults are also written into the OpenAPI schema, so the docs show them.",[336,835,837],{"id":836},"bind-lists","Bind lists",[178,839,840],{},"A slice field accepts either a comma-separated value or a repeated parameter:",[182,842,844],{"className":184,"code":843,"language":186,"meta":187,"style":187},"type FilterRequest struct {\n    Tags []string `query:\"tags\"`\n    IDs  []int    `query:\"id\"`\n}\n",[189,845,846,857,872,888],{"__ignoreMap":187},[192,847,848,850,853,855],{"class":194,"line":195},[192,849,199],{"class":198},[192,851,852],{"class":202}," FilterRequest",[192,854,206],{"class":198},[192,856,209],{"class":198},[192,858,859,862,864,866,868,870],{"class":194,"line":212},[192,860,861],{"class":215},"    Tags ",[192,863,254],{"class":198},[192,865,220],{"class":219},[192,867,259],{"class":198},[192,869,262],{"class":226},[192,871,230],{"class":198},[192,873,874,877,879,881,883,886],{"class":194,"line":233},[192,875,876],{"class":215},"    IDs  ",[192,878,254],{"class":198},[192,880,273],{"class":219},[192,882,794],{"class":198},[192,884,885],{"class":226},"query:\"id\"",[192,887,230],{"class":198},[192,889,890],{"class":194,"line":248},[192,891,334],{"class":198},[182,893,898],{"className":894,"code":895,"filename":896,"language":897,"meta":187,"style":187},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl 'localhost:8080\u002Fitems?tags=go,http&id=1&id=2'\n","Terminal","bash",[189,899,900],{"__ignoreMap":187},[192,901,902,905,908,911],{"class":194,"line":195},[192,903,904],{"class":202},"curl",[192,906,907],{"class":198}," '",[192,909,910],{"class":226},"localhost:8080\u002Fitems?tags=go,http&id=1&id=2",[192,912,913],{"class":198},"'\n",[178,915,916,917,920,921,924],{},"Both forms end up as ",[189,918,919],{},"[\"go\",\"http\"]"," and ",[189,922,923],{},"[1,2]",". Values are trimmed of surrounding whitespace.",[336,926,928],{"id":927},"supported-field-types","Supported field types",[178,930,931],{},"Strings, all signed and unsigned integer widths, floats, booleans, slices of those, and pointers to those. A pointer field is allocated on demand, which lets you tell \"absent\" from \"zero\":",[182,933,935],{"className":184,"code":934,"language":186,"meta":187,"style":187},"type PatchRequest struct {\n    Active *bool `query:\"active\"`   \u002F\u002F nil when the parameter is missing\n}\n",[189,936,937,948,968],{"__ignoreMap":187},[192,938,939,941,944,946],{"class":194,"line":195},[192,940,199],{"class":198},[192,942,943],{"class":202}," PatchRequest",[192,945,206],{"class":198},[192,947,209],{"class":198},[192,949,950,953,955,958,960,963,965],{"class":194,"line":212},[192,951,952],{"class":215},"    Active ",[192,954,659],{"class":198},[192,956,957],{"class":219},"bool",[192,959,259],{"class":198},[192,961,962],{"class":226},"query:\"active\"",[192,964,532],{"class":198},[192,966,967],{"class":535},"   \u002F\u002F nil when the parameter is missing\n",[192,969,970],{"class":194,"line":233},[192,971,334],{"class":198},[178,973,974,975,978,979,490,982,490,985,490,988,490,991,490,994,997,998,1000],{},"Booleans accept the ",[189,976,977],{},"strconv.ParseBool"," set: ",[189,980,981],{},"1",[189,983,984],{},"t",[189,986,987],{},"T",[189,989,990],{},"true",[189,992,993],{},"TRUE",[189,995,996],{},"True",", and their false counterparts. A value that fails to convert returns ",[189,999,686],{}," naming the parameter:",[182,1002,1004],{"className":690,"code":1003,"language":436,"meta":187,"style":187},"{\n  \"error\": true,\n  \"message\": \"failed to set query parameter limit: strconv.ParseInt: parsing \\\"abc\\\": invalid syntax\",\n  \"status\": 400\n}\n",[189,1005,1006,1010,1022,1052,1064],{"__ignoreMap":187},[192,1007,1008],{"class":194,"line":195},[192,1009,698],{"class":198},[192,1011,1012,1014,1016,1018,1020],{"class":194,"line":212},[192,1013,703],{"class":198},[192,1015,706],{"class":219},[192,1017,709],{"class":198},[192,1019,712],{"class":198},[192,1021,715],{"class":198},[192,1023,1024,1026,1028,1030,1032,1034,1037,1040,1043,1045,1048,1050],{"class":194,"line":233},[192,1025,703],{"class":198},[192,1027,722],{"class":219},[192,1029,709],{"class":198},[192,1031,712],{"class":198},[192,1033,729],{"class":198},[192,1035,1036],{"class":226},"failed to set query parameter limit: strconv.ParseInt: parsing ",[192,1038,1039],{"class":215},"\\\"",[192,1041,1042],{"class":226},"abc",[192,1044,1039],{"class":215},[192,1046,1047],{"class":226},": invalid syntax",[192,1049,709],{"class":198},[192,1051,737],{"class":198},[192,1053,1054,1056,1058,1060,1062],{"class":194,"line":248},[192,1055,703],{"class":198},[192,1057,744],{"class":219},[192,1059,709],{"class":198},[192,1061,712],{"class":198},[192,1063,752],{"class":751},[192,1065,1066],{"class":194,"line":267},[192,1067,334],{"class":198},[178,1069,1070,1071,1074],{},"Unexported fields are skipped. Anything else, such as a ",[189,1072,1073],{},"time.Time"," from a query parameter, needs to be taken as a string and parsed in the handler.",[336,1076,1078],{"id":1077},"read-form-submissions","Read form submissions",[182,1080,1082],{"className":184,"code":1081,"language":186,"meta":187,"style":187},"type ContactRequest struct {\n    Name    string `form:\"name\" validate:\"required\"`\n    Email   string `form:\"email\" validate:\"required,email\"`\n    Message string `form:\"message\" validate:\"required,min=10\"`\n}\n\napp.POST(\"\u002Fcontact\", ezz.H(func(ctx *ezz.Context, req ContactRequest) (*Ack, error) {\n    return &Ack{Received: true}, nil\n})).Public()\n",[189,1083,1084,1095,1108,1121,1135,1139,1145,1218,1247],{"__ignoreMap":187},[192,1085,1086,1088,1091,1093],{"class":194,"line":195},[192,1087,199],{"class":198},[192,1089,1090],{"class":202}," ContactRequest",[192,1092,206],{"class":198},[192,1094,209],{"class":198},[192,1096,1097,1099,1101,1103,1106],{"class":194,"line":212},[192,1098,613],{"class":215},[192,1100,220],{"class":219},[192,1102,259],{"class":198},[192,1104,1105],{"class":226},"form:\"name\" validate:\"required\"",[192,1107,230],{"class":198},[192,1109,1110,1112,1114,1116,1119],{"class":194,"line":233},[192,1111,627],{"class":215},[192,1113,220],{"class":219},[192,1115,259],{"class":198},[192,1117,1118],{"class":226},"form:\"email\" validate:\"required,email\"",[192,1120,230],{"class":198},[192,1122,1123,1126,1128,1130,1133],{"class":194,"line":248},[192,1124,1125],{"class":215},"    Message ",[192,1127,220],{"class":219},[192,1129,259],{"class":198},[192,1131,1132],{"class":226},"form:\"message\" validate:\"required,min=10\"",[192,1134,230],{"class":198},[192,1136,1137],{"class":194,"line":267},[192,1138,334],{"class":198},[192,1140,1141],{"class":194,"line":284},[192,1142,1144],{"emptyLinePlaceholder":1143},true,"\n",[192,1146,1147,1150,1152,1155,1158,1160,1163,1165,1168,1171,1173,1176,1179,1183,1186,1189,1191,1193,1195,1198,1200,1203,1206,1209,1211,1214,1216],{"class":194,"line":299},[192,1148,1149],{"class":215},"app",[192,1151,680],{"class":198},[192,1153,591],{"class":1154},"s2Zo4",[192,1156,1157],{"class":198},"(",[192,1159,709],{"class":198},[192,1161,1162],{"class":226},"\u002Fcontact",[192,1164,709],{"class":198},[192,1166,1167],{"class":198},",",[192,1169,1170],{"class":215}," ezz",[192,1172,680],{"class":198},[192,1174,1175],{"class":1154},"H",[192,1177,1178],{"class":198},"(func(",[192,1180,1182],{"class":1181},"sHdIc","ctx",[192,1184,1185],{"class":198}," *",[192,1187,1188],{"class":202},"ezz",[192,1190,680],{"class":198},[192,1192,53],{"class":202},[192,1194,1167],{"class":198},[192,1196,1197],{"class":1181}," req",[192,1199,1090],{"class":202},[192,1201,1202],{"class":198},")",[192,1204,1205],{"class":198}," (*",[192,1207,1208],{"class":202},"Ack",[192,1210,1167],{"class":198},[192,1212,1213],{"class":219}," error",[192,1215,1202],{"class":198},[192,1217,209],{"class":198},[192,1219,1220,1224,1227,1229,1232,1235,1237,1241,1244],{"class":194,"line":314},[192,1221,1223],{"class":1222},"s7zQu","    return",[192,1225,1226],{"class":198}," &",[192,1228,1208],{"class":202},[192,1230,1231],{"class":198},"{",[192,1233,1234],{"class":215},"Received",[192,1236,712],{"class":198},[192,1238,1240],{"class":1239},"sfNiH"," true",[192,1242,1243],{"class":198},"},",[192,1245,1246],{"class":198}," nil\n",[192,1248,1249,1252,1255],{"class":194,"line":331},[192,1250,1251],{"class":198},"})).",[192,1253,1254],{"class":1154},"Public",[192,1256,1257],{"class":198},"()\n",[178,1259,1260,1262,1263,1265,1266,1269,1270,1273],{},[189,1261,424],{}," is called once per request, and only if the struct has at least one ",[189,1264,418],{}," field. It covers ",[189,1267,1268],{},"application\u002Fx-www-form-urlencoded"," bodies and query values. For file uploads, reach for ",[189,1271,1272],{},"ctx.Request.FormFile"," directly.",[336,1275,1277],{"id":1276},"bind-by-hand","Bind by hand",[178,1279,1280,1281,1284],{},"The same machinery is exported for cases outside a typed handler, such as a plain ",[189,1282,1283],{},"http.Handler"," or a background worker replaying stored requests.",[182,1286,1288],{"className":184,"code":1287,"language":186,"meta":187,"style":187},"import \"github.com\u002Fsulv-io\u002Fezz\u002Fbinding\"\n\nvar req CreateUserRequest\nif err := binding.Bind(r, &req); err != nil {\n    \u002F\u002F 400\n}\nif err := binding.Validate(req); err != nil {\n    \u002F\u002F 400\n}\n",[189,1289,1290,1303,1307,1318,1362,1367,1371,1400,1404],{"__ignoreMap":187},[192,1291,1292,1295,1297,1300],{"class":194,"line":195},[192,1293,1294],{"class":1222},"import",[192,1296,729],{"class":198},[192,1298,1299],{"class":202},"github.com\u002Fsulv-io\u002Fezz\u002Fbinding",[192,1301,1302],{"class":198},"\"\n",[192,1304,1305],{"class":194,"line":212},[192,1306,1144],{"emptyLinePlaceholder":1143},[192,1308,1309,1312,1315],{"class":194,"line":233},[192,1310,1311],{"class":198},"var",[192,1313,1314],{"class":215}," req ",[192,1316,1317],{"class":202},"CreateUserRequest\n",[192,1319,1320,1323,1326,1329,1332,1334,1337,1339,1342,1344,1346,1349,1352,1354,1357,1360],{"class":194,"line":248},[192,1321,1322],{"class":1222},"if",[192,1324,1325],{"class":215}," err ",[192,1327,1328],{"class":198},":=",[192,1330,1331],{"class":215}," binding",[192,1333,680],{"class":198},[192,1335,1336],{"class":1154},"Bind",[192,1338,1157],{"class":198},[192,1340,1341],{"class":215},"r",[192,1343,1167],{"class":198},[192,1345,1226],{"class":198},[192,1347,1348],{"class":215},"req",[192,1350,1351],{"class":198},");",[192,1353,1325],{"class":215},[192,1355,1356],{"class":198},"!=",[192,1358,1359],{"class":198}," nil",[192,1361,209],{"class":198},[192,1363,1364],{"class":194,"line":267},[192,1365,1366],{"class":535},"    \u002F\u002F 400\n",[192,1368,1369],{"class":194,"line":284},[192,1370,334],{"class":198},[192,1372,1373,1375,1377,1379,1381,1383,1386,1388,1390,1392,1394,1396,1398],{"class":194,"line":299},[192,1374,1322],{"class":1222},[192,1376,1325],{"class":215},[192,1378,1328],{"class":198},[192,1380,1331],{"class":215},[192,1382,680],{"class":198},[192,1384,1385],{"class":1154},"Validate",[192,1387,1157],{"class":198},[192,1389,1348],{"class":215},[192,1391,1351],{"class":198},[192,1393,1325],{"class":215},[192,1395,1356],{"class":198},[192,1397,1359],{"class":198},[192,1399,209],{"class":198},[192,1401,1402],{"class":194,"line":314},[192,1403,1366],{"class":535},[192,1405,1406],{"class":194,"line":331},[192,1407,334],{"class":198},[341,1409,1410,1420],{},[344,1411,1412],{},[347,1413,1414,1417],{},[350,1415,1416],{},"Function",[350,1418,1419],{},"Purpose",[360,1421,1422,1432,1442,1452,1462,1472],{},[347,1423,1424,1429],{},[365,1425,1426],{},[189,1427,1428],{},"binding.Bind(r, target)",[365,1430,1431],{},"Full binding: body, then path, query, header, form",[347,1433,1434,1439],{},[365,1435,1436],{},[189,1437,1438],{},"binding.BindJSON(r, target)",[365,1440,1441],{},"Body only",[347,1443,1444,1449],{},[365,1445,1446],{},[189,1447,1448],{},"binding.BindQuery(values, target)",[365,1450,1451],{},"Query values only, falling back to lowercased field names",[347,1453,1454,1459],{},[365,1455,1456],{},[189,1457,1458],{},"binding.BindPath(r, target)",[365,1460,1461],{},"Path parameters only",[347,1463,1464,1469],{},[365,1465,1466],{},[189,1467,1468],{},"binding.NewBinder(type)",[365,1470,1471],{},"A reusable binder for one type",[347,1473,1474,1479],{},[365,1475,1476],{},[189,1477,1478],{},"binding.NewValidator(type)",[365,1480,1481],{},"A reusable validator for one type",[178,1483,1484],{},"Reflection metadata for each struct is cached the first time it is seen, so repeated binding of the same type does not re-walk the fields.",[336,1486,1488],{"id":1487},"next-steps","Next steps",[1490,1491,1492,1498],"ul",{},[474,1493,1494,1497],{},[1495,1496,48],"a",{"href":49}," for the rules that run after binding.",[474,1499,1500,1502],{},[1495,1501,131],{"href":132}," for how these tags turn into parameters and schemas.",[1504,1505,1506],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":187,"searchDepth":212,"depth":212,"links":1508},[1509,1510,1511,1512,1513,1514,1515,1516,1517],{"id":338,"depth":212,"text":339},{"id":465,"depth":212,"text":466},{"id":578,"depth":212,"text":579},{"id":759,"depth":212,"text":760},{"id":836,"depth":212,"text":837},{"id":927,"depth":212,"text":928},{"id":1077,"depth":212,"text":1078},{"id":1276,"depth":212,"text":1277},{"id":1487,"depth":212,"text":1488},"Fill your request struct from the path, query string, headers, form fields, and JSON body.","md",null,{},{"icon":46},{"title":43,"description":1518},"dVVcCkHPPQN0o8AnmWScez_umI1prajdX6A3YgBfJiQ",[1526,1528],{"title":38,"path":39,"stem":40,"description":1527,"icon":41,"children":-1},"Write typed handlers with ezz.H and ezz.HFunc, and control how responses are written.",{"title":48,"path":49,"stem":50,"description":1529,"icon":51,"children":-1},"Reject bad input with validate tags before your handler runs.",1784970045269]