[{"data":1,"prerenderedAt":4390},["ShallowReactive",2],{"navigation":3,"/essentials/typed-io":283,"/essentials/typed-io-surround":4385},[4,16,20,68,128,168,179,259,263,267,271,275,279],{"title":5,"path":6,"stem":7,"children":8},"Getting Started","/getting-started","1.getting-started",[9,12],{"title":10,"path":6,"stem":11},"Introduction","1.getting-started/index",{"title":13,"path":14,"stem":15},"Installation","/getting-started/installation","1.getting-started/1.installation",{"title":17,"path":18,"stem":19},"Upgrading","/upgrading","10.upgrading",{"title":21,"path":22,"stem":23,"children":24},"Essentials","/essentials","2.essentials",[25,28,32,36,40,44,48,52,56,60,64],{"title":26,"path":22,"stem":27},"Core concepts","2.essentials/index",{"title":29,"path":30,"stem":31},"Routing","/essentials/routing","2.essentials/1.routing",{"title":33,"path":34,"stem":35},"Typed Requests & Responses","/essentials/typed-io","2.essentials/10.typed-io",{"title":37,"path":38,"stem":39},"Authentication","/essentials/authentication","2.essentials/2.authentication",{"title":41,"path":42,"stem":43},"Identity & User Store","/essentials/identity","2.essentials/3.identity",{"title":45,"path":46,"stem":47},"Requests & Responses","/essentials/requests-responses","2.essentials/4.requests-responses",{"title":49,"path":50,"stem":51},"Controllers","/essentials/controllers","2.essentials/5.controllers",{"title":53,"path":54,"stem":55},"Database","/essentials/database","2.essentials/6.database",{"title":57,"path":58,"stem":59},"Validation","/essentials/validation","2.essentials/7.validation",{"title":61,"path":62,"stem":63},"Migrations","/essentials/migrations","2.essentials/8.migrations",{"title":65,"path":66,"stem":67},"ORM Models","/essentials/orm","2.essentials/9.orm",{"title":69,"path":70,"stem":71,"children":72},"Features","/features","3.features",[73,76,80,84,88,92,96,100,104,108,112,116,120,124],{"title":74,"path":70,"stem":75},"Built‑in Capabilities","3.features/index",{"title":77,"path":78,"stem":79},"API Keys & Scopes","/features/api-keys","3.features/api-keys",{"title":81,"path":82,"stem":83},"Browser Sessions (Cookie Auth)","/features/browser-sessions","3.features/browser-sessions",{"title":85,"path":86,"stem":87},"Caching","/features/caching","3.features/caching",{"title":89,"path":90,"stem":91},"CORS & CSRF","/features/cors-csrf","3.features/cors-csrf",{"title":93,"path":94,"stem":95},"Distributed Locks","/features/distributed-locks","3.features/distributed-locks",{"title":97,"path":98,"stem":99},"Events & Listeners","/features/events","3.features/events",{"title":101,"path":102,"stem":103},"Field Selection","/features/field-selection","3.features/field-selection",{"title":105,"path":106,"stem":107},"File Uploads","/features/file-uploads","3.features/file-uploads",{"title":109,"path":110,"stem":111},"Notifications","/features/notifications","3.features/notifications",{"title":113,"path":114,"stem":115},"Queues & Jobs","/features/queues-jobs","3.features/queues-jobs",{"title":117,"path":118,"stem":119},"Rate Limiting","/features/rate-limiting","3.features/rate-limiting",{"title":121,"path":122,"stem":123},"Task Scheduling","/features/scheduling","3.features/scheduling",{"title":125,"path":126,"stem":127},"Webhooks","/features/webhooks","3.features/webhooks",{"title":129,"path":130,"stem":131,"children":132},"Advanced","/advanced","4.advanced",[133,136,140,144,148,152,156,160,164],{"title":134,"path":130,"stem":135},"Techniques and Patterns","4.advanced/index",{"title":137,"path":138,"stem":139},"Configuration","/advanced/configuration","4.advanced/configuration",{"title":141,"path":142,"stem":143},"Dependency Injection","/advanced/dependency-injection","4.advanced/dependency-injection",{"title":145,"path":146,"stem":147},"Middleware","/advanced/middleware","4.advanced/middleware",{"title":149,"path":150,"stem":151},"OpenAPI Generation","/advanced/openapi","4.advanced/openapi",{"title":153,"path":154,"stem":155},"Performance","/advanced/performance","4.advanced/performance",{"title":157,"path":158,"stem":159},"Repositories","/advanced/repositories","4.advanced/repositories",{"title":161,"path":162,"stem":163},"Service Providers","/advanced/service-providers","4.advanced/service-providers",{"title":165,"path":166,"stem":167},"Testing","/advanced/testing","4.advanced/testing",{"title":169,"path":170,"stem":171,"children":172},"Overview","/tooling","5.tooling",[173,175],{"title":169,"path":170,"stem":174},"5.tooling/index",{"title":176,"path":177,"stem":178},"AI Skills","/tooling/ai-skills","5.tooling/1.ai-skills",{"title":180,"path":181,"stem":182,"children":183},"Cookbook","/cookbook","6.cookbook",[184,187,191,195,199,203,207,211,215,219,223,227,231,235,239,243,247,251,255],{"title":185,"path":181,"stem":186},"Recipes & How‑Tos","6.cookbook/index",{"title":188,"path":189,"stem":190},"Routing Recipes","/cookbook/routing","6.cookbook/1.routing",{"title":192,"path":193,"stem":194},"Caching Recipes","/cookbook/caching","6.cookbook/10.caching",{"title":196,"path":197,"stem":198},"Queue Infrastructure","/cookbook/queues-and-jobs","6.cookbook/11.queues-and-jobs",{"title":200,"path":201,"stem":202},"Notification Channels & Templates","/cookbook/notifications","6.cookbook/13.notifications",{"title":204,"path":205,"stem":206},"Storage","/cookbook/storage","6.cookbook/15.storage",{"title":208,"path":209,"stem":210},"Image Processing Examples","/cookbook/image-processing","6.cookbook/16.image-processing",{"title":212,"path":213,"stem":214},"Permissions and Authorization","/cookbook/permissions-and-authorization","6.cookbook/18.permissions-and-authorization",{"title":216,"path":217,"stem":218},"Session Analytics","/cookbook/sessions-analytics","6.cookbook/19.sessions-analytics",{"title":220,"path":221,"stem":222},"Writing Middleware","/cookbook/middleware","6.cookbook/2.middleware",{"title":224,"path":225,"stem":226},"API Metrics","/cookbook/api-metrics","6.cookbook/20.api-metrics",{"title":228,"path":229,"stem":230},"Performance Recipes","/cookbook/performance","6.cookbook/21.performance",{"title":232,"path":233,"stem":234},"Memory Management","/cookbook/memory-management","6.cookbook/22.memory-management",{"title":236,"path":237,"stem":238},"Writing Console Commands","/cookbook/console-commands","6.cookbook/23.console-commands",{"title":240,"path":241,"stem":242},"Glueful Extensions","/cookbook/extensions","6.cookbook/25.extensions",{"title":244,"path":245,"stem":246},"Error Handling","/cookbook/error-handling","6.cookbook/4.error-handling",{"title":248,"path":249,"stem":250},"Security Guide","/cookbook/security","6.cookbook/5.security",{"title":252,"path":253,"stem":254},"Service Options Resolver","/cookbook/configuration","6.cookbook/6.configuration",{"title":256,"path":257,"stem":258},"Logging","/cookbook/logging","6.cookbook/7.logging",{"title":260,"path":261,"stem":262},"API Reference","/api-reference","7.api-reference",{"title":264,"path":265,"stem":266},"CLI Reference","/cli-reference","8.cli-reference",{"title":268,"path":269,"stem":270},"Extensions","/extensions","9.extensions",{"title":272,"path":273,"stem":274},"Contributing","/contributing","contributing",{"title":276,"path":277,"stem":278},"Release Notes","/releases","releases",{"title":280,"path":281,"stem":282},"Release Archive","/releases-archive","releases-archive",{"id":284,"title":33,"body":285,"description":4379,"extension":4380,"links":4381,"meta":4382,"navigation":391,"path":34,"seo":4383,"stem":35,"__hash__":4384},"docs/2.essentials/10.typed-io.md",{"type":286,"value":287,"toc":4364},"minimark",[288,292,326,337,342,353,700,703,772,827,830,853,858,868,932,935,991,1014,1018,1025,1168,1184,1187,1197,1473,1557,1609,1613,1635,1942,1983,1987,2006,2260,2263,2283,2287,2300,2484,2735,2921,2927,3016,3027,3034,3040,3044,3054,3136,3152,3310,3314,3324,3542,3550,3569,4046,4205,4215,4222,4228,4232,4326,4330,4360],[289,290,291],"p",{},"Glueful's typed I/O layer turns an endpoint's contract into two plain PHP classes:",[293,294,295,313],"ul",{},[296,297,298,299,303,304,308,309,312],"li",{},"A ",[300,301,302],"strong",{},"request DTO"," (",[305,306,307],"code",{},"Glueful\\Validation\\Contracts\\RequestData","). Type-hint it on a controller method and the router hydrates it from the JSON body, path and query string, validates it, and injects it. Invalid input never reaches your code: the client gets a ",[305,310,311],{},"422",".",[296,314,298,315,303,318,321,322,325],{},[300,316,317],{},"response DTO",[305,319,320],{},"Glueful\\Http\\Contracts\\ResponseData","). Return it and the router serializes it into the standard ",[305,323,324],{},"{success, message, data}"," envelope.",[289,327,328,329,333,334,312],{},"Both are read by the ",[330,331,332],"a",{"href":150},"OpenAPI generator",", so the documented schema is the one the code enforces. For the rule syntax itself, see ",[330,335,57],{"href":336},"/essentials/validation#rule-strings",[338,339,341],"h2",{"id":340},"request-dtos","Request DTOs",[289,343,344,345,348,349,352],{},"A request DTO is a class that implements the ",[305,346,347],{},"RequestData"," marker interface and declares its fields as constructor parameters. ",[305,350,351],{},"#[Rule]"," attaches a pipe-separated rule string to each field:",[354,355,360],"pre",{"className":356,"code":357,"language":358,"meta":359,"style":359},"language-php shiki shiki-themes material-theme-lighter github-light github-dark monokai","namespace App\\DTOs;\n\nuse Glueful\\Validation\\Attributes\\Rule;\nuse Glueful\\Validation\\Contracts\\RequestData;\n\nfinal class CreatePostData implements RequestData\n{\n    public function __construct(\n        #[Rule('required|string|max:200')]\n        public readonly string $title,\n\n        #[Rule('required|string')]\n        public readonly string $body,\n\n        #[Rule('in:draft,published')]\n        public readonly string $status = 'draft',\n\n        #[Rule('email')]\n        public readonly ?string $notify = null,\n    ) {}\n}\n","php","",[305,361,362,386,393,421,443,448,469,475,491,519,540,545,565,581,586,606,634,639,659,685,694],{"__ignoreMap":359},[363,364,367,371,375,379,382],"span",{"class":365,"line":366},"line",1,[363,368,370],{"class":369},"shWJe","namespace",[363,372,374],{"class":373},"sKvfc"," App",[363,376,378],{"class":377},"sANao","\\",[363,380,381],{"class":373},"DTOs",[363,383,385],{"class":384},"swvn1",";\n",[363,387,389],{"class":365,"line":388},2,[363,390,392],{"emptyLinePlaceholder":391},true,"\n",[363,394,396,399,403,406,408,410,413,415,419],{"class":365,"line":395},3,[363,397,398],{"class":369},"use",[363,400,402],{"class":401},"s91G_"," Glueful",[363,404,378],{"class":405},"sv8o3",[363,407,57],{"class":401},[363,409,378],{"class":405},[363,411,412],{"class":401},"Attributes",[363,414,378],{"class":405},[363,416,418],{"class":417},"seZir","Rule",[363,420,385],{"class":384},[363,422,424,426,428,430,432,434,437,439,441],{"class":365,"line":423},4,[363,425,398],{"class":369},[363,427,402],{"class":401},[363,429,378],{"class":405},[363,431,57],{"class":401},[363,433,378],{"class":405},[363,435,436],{"class":401},"Contracts",[363,438,378],{"class":405},[363,440,347],{"class":417},[363,442,385],{"class":384},[363,444,446],{"class":365,"line":445},5,[363,447,392],{"emptyLinePlaceholder":391},[363,449,451,455,459,462,465],{"class":365,"line":450},6,[363,452,454],{"class":453},"sTNss","final",[363,456,458],{"class":457},"srJo8"," class",[363,460,461],{"class":373}," CreatePostData",[363,463,464],{"class":453}," implements",[363,466,468],{"class":467},"sW3Pz"," RequestData\n",[363,470,472],{"class":365,"line":471},7,[363,473,474],{"class":384},"{\n",[363,476,478,481,484,488],{"class":365,"line":477},8,[363,479,480],{"class":453},"    public",[363,482,483],{"class":457}," function",[363,485,487],{"class":486},"sMLJd"," __construct",[363,489,490],{"class":384},"(\n",[363,492,494,498,500,503,507,511,513,516],{"class":365,"line":493},9,[363,495,497],{"class":496},"ss--_","        #[",[363,499,418],{"class":401},[363,501,502],{"class":384},"(",[363,504,506],{"class":505},"siCPE","'",[363,508,510],{"class":509},"sLACW","required|string|max:200",[363,512,506],{"class":505},[363,514,515],{"class":384},")",[363,517,518],{"class":496},"]\n",[363,520,522,525,528,531,534,537],{"class":365,"line":521},10,[363,523,524],{"class":453},"        public",[363,526,527],{"class":453}," readonly",[363,529,530],{"class":369}," string",[363,532,533],{"class":384}," $",[363,535,536],{"class":496},"title",[363,538,539],{"class":384},",\n",[363,541,543],{"class":365,"line":542},11,[363,544,392],{"emptyLinePlaceholder":391},[363,546,548,550,552,554,556,559,561,563],{"class":365,"line":547},12,[363,549,497],{"class":496},[363,551,418],{"class":401},[363,553,502],{"class":384},[363,555,506],{"class":505},[363,557,558],{"class":509},"required|string",[363,560,506],{"class":505},[363,562,515],{"class":384},[363,564,518],{"class":496},[363,566,568,570,572,574,576,579],{"class":365,"line":567},13,[363,569,524],{"class":453},[363,571,527],{"class":453},[363,573,530],{"class":369},[363,575,533],{"class":384},[363,577,578],{"class":496},"body",[363,580,539],{"class":384},[363,582,584],{"class":365,"line":583},14,[363,585,392],{"emptyLinePlaceholder":391},[363,587,589,591,593,595,597,600,602,604],{"class":365,"line":588},15,[363,590,497],{"class":496},[363,592,418],{"class":401},[363,594,502],{"class":384},[363,596,506],{"class":505},[363,598,599],{"class":509},"in:draft,published",[363,601,506],{"class":505},[363,603,515],{"class":384},[363,605,518],{"class":496},[363,607,609,611,613,615,617,620,624,627,630,632],{"class":365,"line":608},16,[363,610,524],{"class":453},[363,612,527],{"class":453},[363,614,530],{"class":369},[363,616,533],{"class":384},[363,618,619],{"class":496},"status ",[363,621,623],{"class":622},"sGXK2","=",[363,625,626],{"class":505}," '",[363,628,629],{"class":509},"draft",[363,631,506],{"class":505},[363,633,539],{"class":384},[363,635,637],{"class":365,"line":636},17,[363,638,392],{"emptyLinePlaceholder":391},[363,640,642,644,646,648,650,653,655,657],{"class":365,"line":641},18,[363,643,497],{"class":496},[363,645,418],{"class":401},[363,647,502],{"class":384},[363,649,506],{"class":505},[363,651,652],{"class":509},"email",[363,654,506],{"class":505},[363,656,515],{"class":384},[363,658,518],{"class":496},[363,660,662,664,666,669,672,674,677,679,683],{"class":365,"line":661},19,[363,663,524],{"class":453},[363,665,527],{"class":453},[363,667,668],{"class":622}," ?",[363,670,671],{"class":369},"string",[363,673,533],{"class":384},[363,675,676],{"class":496},"notify ",[363,678,623],{"class":622},[363,680,682],{"class":681},"sMTiH"," null",[363,684,539],{"class":384},[363,686,688,691],{"class":365,"line":687},20,[363,689,690],{"class":384},"    )",[363,692,693],{"class":384}," {}\n",[363,695,697],{"class":365,"line":696},21,[363,698,699],{"class":384},"}\n",[289,701,702],{},"Type-hint it on the handler. No middleware is needed:",[354,704,706],{"className":356,"code":705,"language":358,"meta":359,"style":359},"use App\\DTOs\\CreatePostData;\n\npublic function store(CreatePostData $data): Response\n{\n    // $data->title, $data->body, $data->status are validated and typed\n}\n",[305,707,708,725,729,758,762,768],{"__ignoreMap":359},[363,709,710,712,714,716,718,720,723],{"class":365,"line":366},[363,711,398],{"class":369},[363,713,374],{"class":401},[363,715,378],{"class":405},[363,717,381],{"class":401},[363,719,378],{"class":405},[363,721,722],{"class":417},"CreatePostData",[363,724,385],{"class":384},[363,726,727],{"class":365,"line":388},[363,728,392],{"emptyLinePlaceholder":391},[363,730,731,734,736,740,742,745,747,750,752,755],{"class":365,"line":395},[363,732,733],{"class":453},"public",[363,735,483],{"class":457},[363,737,739],{"class":738},"sD0ED"," store",[363,741,502],{"class":384},[363,743,722],{"class":744},"s_MOj",[363,746,533],{"class":384},[363,748,749],{"class":496},"data",[363,751,515],{"class":384},[363,753,754],{"class":622},":",[363,756,757],{"class":744}," Response\n",[363,759,760],{"class":365,"line":423},[363,761,474],{"class":384},[363,763,764],{"class":365,"line":445},[363,765,767],{"class":766},"ss7Ak","    // $data->title, $data->body, $data->status are validated and typed\n",[363,769,770],{"class":365,"line":450},[363,771,699],{"class":384},[354,773,775],{"className":356,"code":774,"language":358,"meta":359,"style":359},"$router->post('/posts', [PostController::class, 'store']);\n",[305,776,777],{"__ignoreMap":359},[363,778,779,782,785,788,791,793,795,798,800,803,806,809,812,815,817,819,822,824],{"class":365,"line":366},[363,780,781],{"class":384},"$",[363,783,784],{"class":496},"router",[363,786,787],{"class":622},"->",[363,789,790],{"class":738},"post",[363,792,502],{"class":384},[363,794,506],{"class":505},[363,796,797],{"class":509},"/posts",[363,799,506],{"class":505},[363,801,802],{"class":384},",",[363,804,805],{"class":384}," [",[363,807,808],{"class":744},"PostController",[363,810,811],{"class":622},"::",[363,813,814],{"class":369},"class",[363,816,802],{"class":384},[363,818,626],{"class":505},[363,820,821],{"class":509},"store",[363,823,506],{"class":505},[363,825,826],{"class":384},"]);\n",[289,828,829],{},"Scaffold one with:",[354,831,835],{"className":832,"code":833,"language":834,"meta":359,"style":359},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark monokai","php glueful scaffold:dto CreatePostData        # writes app/DTOs/CreatePostData.php\n","bash",[305,836,837],{"__ignoreMap":359},[363,838,839,842,845,848,850],{"class":365,"line":366},[363,840,358],{"class":841},"sR7ES",[363,843,844],{"class":509}," glueful",[363,846,847],{"class":509}," scaffold:dto",[363,849,461],{"class":509},[363,851,852],{"class":766},"        # writes app/DTOs/CreatePostData.php\n",[854,855,857],"h3",{"id":856},"how-hydration-works","How Hydration Works",[289,859,860,861,863,864,867],{},"When the router resolves a parameter whose type implements ",[305,862,347],{},", ",[305,865,866],{},"Glueful\\Validation\\RequestDataHydrator"," builds it in a fixed order:",[869,870,871,882,891,900,913,923],"ol",{},[296,872,873,876,877,881],{},[300,874,875],{},"Resolve each field from its source",": the JSON body by default, or the path/query (see ",[330,878,880],{"href":879},"#route-and-query-fields","Route and Query Fields",").",[296,883,884,890],{},[300,885,886,887,889],{},"Run the ",[305,888,351],{}," strings"," over the resolved values.",[296,892,893,896,897,312],{},[300,894,895],{},"Hydrate arrays and nested DTOs"," declared with ",[305,898,899],{},"#[ArrayOf]",[296,901,902,905,906,909,910,312],{},[300,903,904],{},"Check required presence."," A non-nullable parameter with no default that is missing from the input becomes a 422 (",[305,907,908],{},"The {field} field is required.","), not a ",[305,911,912],{},"TypeError",[296,914,915,918,919,922],{},[300,916,917],{},"Fail before constructing."," Any error so far throws ",[305,920,921],{},"ValidationException",", so the DTO is never built with partial data.",[296,924,925,931],{},[300,926,927,928],{},"Run ",[305,929,930],{},"ValidatesSelf::validate()",", if implemented, on the constructed object.",[289,933,934],{},"Binding rules:",[293,936,937,950,956,975],{},[296,938,939,942,943,946,947,312],{},[300,940,941],{},"Property names are the exact input keys."," There is no snake_case/camelCase conversion: ",[305,944,945],{},"$refresh_token"," reads ",[305,948,949],{},"refresh_token",[296,951,952,955],{},[300,953,954],{},"Defaults and nullables fill in"," when a key is absent.",[296,957,958,961,962,863,965,863,968,971,972,974],{},[300,959,960],{},"Scalars are coerced"," to the declared ",[305,963,964],{},"int",[305,966,967],{},"float",[305,969,970],{},"bool"," or ",[305,973,671],{}," type after validation.",[296,976,977,980,981,984,985,987,988,881],{},[300,978,979],{},"The body must be JSON."," Form-encoded and multipart bodies are not read. An empty body counts as ",[305,982,983],{},"{}",". Malformed JSON fails with a ",[305,986,578],{}," error (",[305,989,990],{},"Invalid JSON body.",[992,993,997],"u-alert",{"color":994,"icon":995,"variant":996},"warning","i-tabler-alert-triangle","subtle",[998,999,1000],"template",{"v-slot:description":359},[289,1001,1002,1003,1006,1007,1010,1011,1013],{},"Give typed scalar fields a matching rule. Coercion only converts values that fit (",[305,1004,1005],{},"\"42\""," → ",[305,1008,1009],{},"42","). A non-numeric string reaching an ",[305,1012,964],{}," parameter with no rule to reject it surfaces as a type error rather than a 422.",[854,1015,1017],{"id":1016},"the-422-envelope","The 422 Envelope",[289,1019,1020,1021,1024],{},"All failures, including field rules, nested elements and ",[305,1022,1023],{},"ValidatesSelf",", merge into one response:",[354,1026,1030],{"className":1027,"code":1028,"language":1029,"meta":359,"style":359},"language-json shiki shiki-themes material-theme-lighter github-light github-dark monokai","{\n  \"success\": false,\n  \"message\": \"The given data was invalid.\",\n  \"errors\": {\n    \"title\": [\"This field is required.\"],\n    \"items.1.sku\": [\"This field is required.\"],\n    \"coupon_ids.2\": [\"The coupon_ids.2 field must be of type int.\"]\n  }\n}\n","json",[305,1031,1032,1036,1056,1079,1093,1116,1137,1159,1164],{"__ignoreMap":359},[363,1033,1034],{"class":365,"line":366},[363,1035,474],{"class":384},[363,1037,1038,1042,1046,1049,1051,1054],{"class":365,"line":388},[363,1039,1041],{"class":1040},"saDeg","  \"",[363,1043,1045],{"class":1044},"sEff5","success",[363,1047,1048],{"class":1040},"\"",[363,1050,754],{"class":384},[363,1052,1053],{"class":681}," false",[363,1055,539],{"class":384},[363,1057,1058,1060,1063,1065,1067,1071,1075,1077],{"class":365,"line":395},[363,1059,1041],{"class":1040},[363,1061,1062],{"class":1044},"message",[363,1064,1048],{"class":1040},[363,1066,754],{"class":384},[363,1068,1070],{"class":1069},"sh1VR"," \"",[363,1072,1074],{"class":1073},"sINAO","The given data was invalid.",[363,1076,1048],{"class":1069},[363,1078,539],{"class":384},[363,1080,1081,1083,1086,1088,1090],{"class":365,"line":423},[363,1082,1041],{"class":1040},[363,1084,1085],{"class":1044},"errors",[363,1087,1048],{"class":1040},[363,1089,754],{"class":384},[363,1091,1092],{"class":384}," {\n",[363,1094,1095,1098,1100,1102,1104,1106,1108,1111,1113],{"class":365,"line":445},[363,1096,1097],{"class":1040},"    \"",[363,1099,536],{"class":744},[363,1101,1048],{"class":1040},[363,1103,754],{"class":384},[363,1105,805],{"class":384},[363,1107,1048],{"class":1069},[363,1109,1110],{"class":1073},"This field is required.",[363,1112,1048],{"class":1069},[363,1114,1115],{"class":384},"],\n",[363,1117,1118,1120,1123,1125,1127,1129,1131,1133,1135],{"class":365,"line":450},[363,1119,1097],{"class":1040},[363,1121,1122],{"class":744},"items.1.sku",[363,1124,1048],{"class":1040},[363,1126,754],{"class":384},[363,1128,805],{"class":384},[363,1130,1048],{"class":1069},[363,1132,1110],{"class":1073},[363,1134,1048],{"class":1069},[363,1136,1115],{"class":384},[363,1138,1139,1141,1144,1146,1148,1150,1152,1155,1157],{"class":365,"line":471},[363,1140,1097],{"class":1040},[363,1142,1143],{"class":744},"coupon_ids.2",[363,1145,1048],{"class":1040},[363,1147,754],{"class":384},[363,1149,805],{"class":384},[363,1151,1048],{"class":1069},[363,1153,1154],{"class":1073},"The coupon_ids.2 field must be of type int.",[363,1156,1048],{"class":1069},[363,1158,518],{"class":384},[363,1160,1161],{"class":365,"line":477},[363,1162,1163],{"class":384},"  }\n",[363,1165,1166],{"class":365,"line":493},[363,1167,699],{"class":384},[289,1169,1170,1171,863,1174,1177,1178,1181,1182,312],{},"Database rules (",[305,1172,1173],{},"unique:",[305,1175,1176],{},"exists:",") run against the application's connection. Custom rule names resolve through the ",[305,1179,1180],{},"RuleRegistry",", as described in ",[330,1183,57],{"href":336},[338,1185,880],{"id":1186},"route-and-query-fields",[289,1188,1189,1192,1193,1196],{},[305,1190,1191],{},"#[FromRoute]"," reads a field from the matched path parameters, and ",[305,1194,1195],{},"#[FromQuery]"," reads it from the query string. Everything else comes from the body:",[354,1198,1200],{"className":356,"code":1199,"language":358,"meta":359,"style":359},"use Glueful\\Validation\\Attributes\\{FromQuery, FromRoute, Rule};\nuse Glueful\\Validation\\Contracts\\RequestData;\n\nfinal class UpdatePostData implements RequestData\n{\n    public function __construct(\n        #[FromRoute(description: 'Post UUID')]\n        public readonly string $uuid,                        // /posts/{uuid}\n\n        #[FromQuery(description: 'Notify subscribers', example: 'true')]\n        #[Rule('in:true,false')]\n        public readonly string $notify = 'false',            // ?notify=true\n\n        #[Rule('required|string|max:200')]\n        public readonly string $title = '',                  // JSON body\n    ) {}\n}\n",[305,1201,1202,1237,1257,1261,1274,1278,1288,1314,1332,1336,1373,1392,1418,1422,1440,1463,1469],{"__ignoreMap":359},[363,1203,1204,1206,1208,1210,1212,1214,1216,1218,1221,1224,1226,1229,1231,1234],{"class":365,"line":366},[363,1205,398],{"class":369},[363,1207,402],{"class":401},[363,1209,378],{"class":405},[363,1211,57],{"class":401},[363,1213,378],{"class":405},[363,1215,412],{"class":401},[363,1217,378],{"class":405},[363,1219,1220],{"class":384},"{",[363,1222,1223],{"class":417},"FromQuery",[363,1225,802],{"class":384},[363,1227,1228],{"class":417}," FromRoute",[363,1230,802],{"class":384},[363,1232,1233],{"class":417}," Rule",[363,1235,1236],{"class":384},"};\n",[363,1238,1239,1241,1243,1245,1247,1249,1251,1253,1255],{"class":365,"line":388},[363,1240,398],{"class":369},[363,1242,402],{"class":401},[363,1244,378],{"class":405},[363,1246,57],{"class":401},[363,1248,378],{"class":405},[363,1250,436],{"class":401},[363,1252,378],{"class":405},[363,1254,347],{"class":417},[363,1256,385],{"class":384},[363,1258,1259],{"class":365,"line":395},[363,1260,392],{"emptyLinePlaceholder":391},[363,1262,1263,1265,1267,1270,1272],{"class":365,"line":423},[363,1264,454],{"class":453},[363,1266,458],{"class":457},[363,1268,1269],{"class":373}," UpdatePostData",[363,1271,464],{"class":453},[363,1273,468],{"class":467},[363,1275,1276],{"class":365,"line":445},[363,1277,474],{"class":384},[363,1279,1280,1282,1284,1286],{"class":365,"line":450},[363,1281,480],{"class":453},[363,1283,483],{"class":457},[363,1285,487],{"class":486},[363,1287,490],{"class":384},[363,1289,1290,1292,1295,1297,1301,1303,1305,1308,1310,1312],{"class":365,"line":471},[363,1291,497],{"class":496},[363,1293,1294],{"class":401},"FromRoute",[363,1296,502],{"class":384},[363,1298,1300],{"class":1299},"sQqfL","description",[363,1302,754],{"class":384},[363,1304,626],{"class":505},[363,1306,1307],{"class":509},"Post UUID",[363,1309,506],{"class":505},[363,1311,515],{"class":384},[363,1313,518],{"class":496},[363,1315,1316,1318,1320,1322,1324,1327,1329],{"class":365,"line":477},[363,1317,524],{"class":453},[363,1319,527],{"class":453},[363,1321,530],{"class":369},[363,1323,533],{"class":384},[363,1325,1326],{"class":496},"uuid",[363,1328,802],{"class":384},[363,1330,1331],{"class":766},"                        // /posts/{uuid}\n",[363,1333,1334],{"class":365,"line":493},[363,1335,392],{"emptyLinePlaceholder":391},[363,1337,1338,1340,1342,1344,1346,1348,1350,1353,1355,1357,1360,1362,1364,1367,1369,1371],{"class":365,"line":521},[363,1339,497],{"class":496},[363,1341,1223],{"class":401},[363,1343,502],{"class":384},[363,1345,1300],{"class":1299},[363,1347,754],{"class":384},[363,1349,626],{"class":505},[363,1351,1352],{"class":509},"Notify subscribers",[363,1354,506],{"class":505},[363,1356,802],{"class":384},[363,1358,1359],{"class":1299}," example",[363,1361,754],{"class":384},[363,1363,626],{"class":505},[363,1365,1366],{"class":509},"true",[363,1368,506],{"class":505},[363,1370,515],{"class":384},[363,1372,518],{"class":496},[363,1374,1375,1377,1379,1381,1383,1386,1388,1390],{"class":365,"line":542},[363,1376,497],{"class":496},[363,1378,418],{"class":401},[363,1380,502],{"class":384},[363,1382,506],{"class":505},[363,1384,1385],{"class":509},"in:true,false",[363,1387,506],{"class":505},[363,1389,515],{"class":384},[363,1391,518],{"class":496},[363,1393,1394,1396,1398,1400,1402,1404,1406,1408,1411,1413,1415],{"class":365,"line":547},[363,1395,524],{"class":453},[363,1397,527],{"class":453},[363,1399,530],{"class":369},[363,1401,533],{"class":384},[363,1403,676],{"class":496},[363,1405,623],{"class":622},[363,1407,626],{"class":505},[363,1409,1410],{"class":509},"false",[363,1412,506],{"class":505},[363,1414,802],{"class":384},[363,1416,1417],{"class":766},"            // ?notify=true\n",[363,1419,1420],{"class":365,"line":567},[363,1421,392],{"emptyLinePlaceholder":391},[363,1423,1424,1426,1428,1430,1432,1434,1436,1438],{"class":365,"line":583},[363,1425,497],{"class":496},[363,1427,418],{"class":401},[363,1429,502],{"class":384},[363,1431,506],{"class":505},[363,1433,510],{"class":509},[363,1435,506],{"class":505},[363,1437,515],{"class":384},[363,1439,518],{"class":496},[363,1441,1442,1444,1446,1448,1450,1453,1455,1458,1460],{"class":365,"line":588},[363,1443,524],{"class":453},[363,1445,527],{"class":453},[363,1447,530],{"class":369},[363,1449,533],{"class":384},[363,1451,1452],{"class":496},"title ",[363,1454,623],{"class":622},[363,1456,1457],{"class":505}," ''",[363,1459,802],{"class":384},[363,1461,1462],{"class":766},"                  // JSON body\n",[363,1464,1465,1467],{"class":365,"line":608},[363,1466,690],{"class":384},[363,1468,693],{"class":384},[363,1470,1471],{"class":365,"line":636},[363,1472,699],{"class":384},[354,1474,1476],{"className":356,"code":1475,"language":358,"meta":359,"style":359},"$router->put('/posts/{uuid}', [PostController::class, 'update']);\n\npublic function update(UpdatePostData $data): Response { /* ... */ }\n",[305,1477,1478,1519,1523],{"__ignoreMap":359},[363,1479,1480,1482,1484,1486,1489,1491,1493,1496,1498,1500,1502,1504,1506,1508,1510,1512,1515,1517],{"class":365,"line":366},[363,1481,781],{"class":384},[363,1483,784],{"class":496},[363,1485,787],{"class":622},[363,1487,1488],{"class":738},"put",[363,1490,502],{"class":384},[363,1492,506],{"class":505},[363,1494,1495],{"class":509},"/posts/{uuid}",[363,1497,506],{"class":505},[363,1499,802],{"class":384},[363,1501,805],{"class":384},[363,1503,808],{"class":744},[363,1505,811],{"class":622},[363,1507,814],{"class":369},[363,1509,802],{"class":384},[363,1511,626],{"class":505},[363,1513,1514],{"class":509},"update",[363,1516,506],{"class":505},[363,1518,826],{"class":384},[363,1520,1521],{"class":365,"line":388},[363,1522,392],{"emptyLinePlaceholder":391},[363,1524,1525,1527,1529,1532,1534,1537,1539,1541,1543,1545,1548,1551,1554],{"class":365,"line":395},[363,1526,733],{"class":453},[363,1528,483],{"class":457},[363,1530,1531],{"class":738}," update",[363,1533,502],{"class":384},[363,1535,1536],{"class":744},"UpdatePostData",[363,1538,533],{"class":384},[363,1540,749],{"class":496},[363,1542,515],{"class":384},[363,1544,754],{"class":622},[363,1546,1547],{"class":744}," Response",[363,1549,1550],{"class":384}," {",[363,1552,1553],{"class":766}," /* ... */",[363,1555,1556],{"class":384}," }\n",[293,1558,1559,1565,1573,1599],{},[296,1560,1561,1562,312],{},"A field has exactly one source. Putting both attributes on one field throws a ",[305,1563,1564],{},"LogicException",[296,1566,1567,1569,1570,1572],{},[305,1568,1191],{}," / ",[305,1571,1195],{}," are valid only on the DTO the handler receives, not on nested DTOs.",[296,1574,1575,1576,863,1578,971,1580,1582,1583,1586,1587,1590,1591,1594,1595,1598],{},"Path and query values arrive as strings. A field declared ",[305,1577,964],{},[305,1579,967],{},[305,1581,970],{}," gets the string converted before its rules run, so ",[305,1584,1585],{},"#[Rule('integer|min:1')]"," works on ",[305,1588,1589],{},"?page=2","; booleans accept ",[305,1592,1593],{},"true/false/1/0/yes/no/on/off",". A value that doesn't convert (",[305,1596,1597],{},"?page=abc",") is a 422: \"The page field must be an integer.\"",[296,1600,1601,1602,1604,1605,1608],{},"The optional ",[305,1603,1300],{}," and ",[305,1606,1607],{},"example"," arguments only feed the OpenAPI parameter.",[338,1610,1612],{"id":1611},"arrays-and-nested-data","Arrays and Nested Data",[289,1614,1615,1616,1619,1620,1622,1623,863,1625,863,1627,863,1629,1631,1632,1634],{},"An ",[305,1617,1618],{},"array"," field is untyped unless you declare its element type with ",[305,1621,899],{},". Use a scalar name (",[305,1624,671],{},[305,1626,964],{},[305,1628,967],{},[305,1630,970],{},") or another ",[305,1633,347],{}," class:",[354,1636,1638],{"className":356,"code":1637,"language":358,"meta":359,"style":359},"use Glueful\\Validation\\Attributes\\{ArrayOf, Rule};\nuse Glueful\\Validation\\Contracts\\RequestData;\n\nfinal class LineItemData implements RequestData\n{\n    public function __construct(\n        #[Rule('required|string')] public readonly string $sku,\n        #[Rule('required|numeric')] public readonly int $quantity,\n    ) {}\n}\n\nfinal class CreateOrderData implements RequestData\n{\n    public function __construct(\n        #[Rule('required|array'), ArrayOf(LineItemData::class)]\n        public readonly array $items,          // list\u003CLineItemData>\n\n        #[Rule('array'), ArrayOf('int')]\n        public readonly array $coupon_ids = [], // list\u003Cint>\n    ) {}\n}\n",[305,1639,1640,1667,1687,1691,1704,1708,1718,1750,1783,1789,1793,1797,1810,1814,1824,1858,1877,1881,1911,1932,1938],{"__ignoreMap":359},[363,1641,1642,1644,1646,1648,1650,1652,1654,1656,1658,1661,1663,1665],{"class":365,"line":366},[363,1643,398],{"class":369},[363,1645,402],{"class":401},[363,1647,378],{"class":405},[363,1649,57],{"class":401},[363,1651,378],{"class":405},[363,1653,412],{"class":401},[363,1655,378],{"class":405},[363,1657,1220],{"class":384},[363,1659,1660],{"class":417},"ArrayOf",[363,1662,802],{"class":384},[363,1664,1233],{"class":417},[363,1666,1236],{"class":384},[363,1668,1669,1671,1673,1675,1677,1679,1681,1683,1685],{"class":365,"line":388},[363,1670,398],{"class":369},[363,1672,402],{"class":401},[363,1674,378],{"class":405},[363,1676,57],{"class":401},[363,1678,378],{"class":405},[363,1680,436],{"class":401},[363,1682,378],{"class":405},[363,1684,347],{"class":417},[363,1686,385],{"class":384},[363,1688,1689],{"class":365,"line":395},[363,1690,392],{"emptyLinePlaceholder":391},[363,1692,1693,1695,1697,1700,1702],{"class":365,"line":423},[363,1694,454],{"class":453},[363,1696,458],{"class":457},[363,1698,1699],{"class":373}," LineItemData",[363,1701,464],{"class":453},[363,1703,468],{"class":467},[363,1705,1706],{"class":365,"line":445},[363,1707,474],{"class":384},[363,1709,1710,1712,1714,1716],{"class":365,"line":450},[363,1711,480],{"class":453},[363,1713,483],{"class":457},[363,1715,487],{"class":486},[363,1717,490],{"class":384},[363,1719,1720,1722,1724,1726,1728,1730,1732,1734,1737,1739,1741,1743,1745,1748],{"class":365,"line":471},[363,1721,497],{"class":496},[363,1723,418],{"class":401},[363,1725,502],{"class":384},[363,1727,506],{"class":505},[363,1729,558],{"class":509},[363,1731,506],{"class":505},[363,1733,515],{"class":384},[363,1735,1736],{"class":496},"] ",[363,1738,733],{"class":453},[363,1740,527],{"class":453},[363,1742,530],{"class":369},[363,1744,533],{"class":384},[363,1746,1747],{"class":496},"sku",[363,1749,539],{"class":384},[363,1751,1752,1754,1756,1758,1760,1763,1765,1767,1769,1771,1773,1776,1778,1781],{"class":365,"line":477},[363,1753,497],{"class":496},[363,1755,418],{"class":401},[363,1757,502],{"class":384},[363,1759,506],{"class":505},[363,1761,1762],{"class":509},"required|numeric",[363,1764,506],{"class":505},[363,1766,515],{"class":384},[363,1768,1736],{"class":496},[363,1770,733],{"class":453},[363,1772,527],{"class":453},[363,1774,1775],{"class":369}," int",[363,1777,533],{"class":384},[363,1779,1780],{"class":496},"quantity",[363,1782,539],{"class":384},[363,1784,1785,1787],{"class":365,"line":493},[363,1786,690],{"class":384},[363,1788,693],{"class":384},[363,1790,1791],{"class":365,"line":521},[363,1792,699],{"class":384},[363,1794,1795],{"class":365,"line":542},[363,1796,392],{"emptyLinePlaceholder":391},[363,1798,1799,1801,1803,1806,1808],{"class":365,"line":547},[363,1800,454],{"class":453},[363,1802,458],{"class":457},[363,1804,1805],{"class":373}," CreateOrderData",[363,1807,464],{"class":453},[363,1809,468],{"class":467},[363,1811,1812],{"class":365,"line":567},[363,1813,474],{"class":384},[363,1815,1816,1818,1820,1822],{"class":365,"line":583},[363,1817,480],{"class":453},[363,1819,483],{"class":457},[363,1821,487],{"class":486},[363,1823,490],{"class":384},[363,1825,1826,1828,1830,1832,1834,1837,1839,1842,1845,1847,1850,1852,1854,1856],{"class":365,"line":588},[363,1827,497],{"class":496},[363,1829,418],{"class":401},[363,1831,502],{"class":384},[363,1833,506],{"class":505},[363,1835,1836],{"class":509},"required|array",[363,1838,506],{"class":505},[363,1840,1841],{"class":384},"),",[363,1843,1844],{"class":401}," ArrayOf",[363,1846,502],{"class":384},[363,1848,1849],{"class":744},"LineItemData",[363,1851,811],{"class":622},[363,1853,814],{"class":369},[363,1855,515],{"class":384},[363,1857,518],{"class":496},[363,1859,1860,1862,1864,1867,1869,1872,1874],{"class":365,"line":608},[363,1861,524],{"class":453},[363,1863,527],{"class":453},[363,1865,1866],{"class":369}," array",[363,1868,533],{"class":384},[363,1870,1871],{"class":496},"items",[363,1873,802],{"class":384},[363,1875,1876],{"class":766},"          // list\u003CLineItemData>\n",[363,1878,1879],{"class":365,"line":636},[363,1880,392],{"emptyLinePlaceholder":391},[363,1882,1883,1885,1887,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907,1909],{"class":365,"line":641},[363,1884,497],{"class":496},[363,1886,418],{"class":401},[363,1888,502],{"class":384},[363,1890,506],{"class":505},[363,1892,1618],{"class":509},[363,1894,506],{"class":505},[363,1896,1841],{"class":384},[363,1898,1844],{"class":401},[363,1900,502],{"class":384},[363,1902,506],{"class":505},[363,1904,964],{"class":509},[363,1906,506],{"class":505},[363,1908,515],{"class":384},[363,1910,518],{"class":496},[363,1912,1913,1915,1917,1919,1921,1924,1926,1929],{"class":365,"line":661},[363,1914,524],{"class":453},[363,1916,527],{"class":453},[363,1918,1866],{"class":369},[363,1920,533],{"class":384},[363,1922,1923],{"class":496},"coupon_ids ",[363,1925,623],{"class":622},[363,1927,1928],{"class":384}," [],",[363,1930,1931],{"class":766}," // list\u003Cint>\n",[363,1933,1934,1936],{"class":365,"line":687},[363,1935,690],{"class":384},[363,1937,693],{"class":384},[363,1939,1940],{"class":365,"line":696},[363,1941,699],{"class":384},[293,1943,1944,1963,1969,1972],{},[296,1945,1946,1947,1949,1950,971,1953,1956,1957,1960,1961,312],{},"Scalar elements are checked and coerced strictly. An ",[305,1948,964],{}," element accepts ",[305,1951,1952],{},"5",[305,1954,1955],{},"\"5\""," but not ",[305,1958,1959],{},"\"5a\"",", and errors are keyed ",[305,1962,1143],{},[296,1964,1965,1966,312],{},"Each nested element must be an object. It is hydrated and validated like a top-level DTO, with errors keyed ",[305,1967,1968],{},"items.0.sku",[296,1970,1971],{},"Nesting is capped at 5 levels.",[296,1973,1974,1976,1977,1979,1980,1982],{},[305,1975,899],{}," with a class that doesn't implement ",[305,1978,347],{}," throws a ",[305,1981,1564],{},". An unknown type name throws when the attribute is read.",[338,1984,1986],{"id":1985},"cross-field-validation","Cross-Field Validation",[289,1988,1989,1990,1993,1994,1997,1998,2001,2002,2005],{},"Implement ",[305,1991,1992],{},"Glueful\\Validation\\Contracts\\ValidatesSelf"," for rules that span fields. ",[305,1995,1996],{},"validate()"," runs after construction, so ",[305,1999,2000],{},"$this"," is fully typed. It returns ",[305,2003,2004],{},"field => list\u003Cstring>",", and an empty array means valid:",[354,2007,2009],{"className":356,"code":2008,"language":358,"meta":359,"style":359},"use Glueful\\Validation\\Attributes\\Rule;\nuse Glueful\\Validation\\Contracts\\{RequestData, ValidatesSelf};\n\nfinal class DateRangeData implements RequestData, ValidatesSelf\n{\n    public function __construct(\n        #[Rule('required|date:Y-m-d')] public readonly string $from,\n        #[Rule('required|date:Y-m-d')] public readonly string $to,\n    ) {}\n\n    public function validate(): array\n    {\n        return $this->from > $this->to\n            ? ['to' => ['The end date must be after the start date.']]\n            : [];\n    }\n}\n",[305,2010,2011,2031,2058,2062,2081,2085,2095,2127,2158,2164,2168,2185,2190,2215,2243,2251,2256],{"__ignoreMap":359},[363,2012,2013,2015,2017,2019,2021,2023,2025,2027,2029],{"class":365,"line":366},[363,2014,398],{"class":369},[363,2016,402],{"class":401},[363,2018,378],{"class":405},[363,2020,57],{"class":401},[363,2022,378],{"class":405},[363,2024,412],{"class":401},[363,2026,378],{"class":405},[363,2028,418],{"class":417},[363,2030,385],{"class":384},[363,2032,2033,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053,2056],{"class":365,"line":388},[363,2034,398],{"class":369},[363,2036,402],{"class":401},[363,2038,378],{"class":405},[363,2040,57],{"class":401},[363,2042,378],{"class":405},[363,2044,436],{"class":401},[363,2046,378],{"class":405},[363,2048,1220],{"class":384},[363,2050,347],{"class":417},[363,2052,802],{"class":384},[363,2054,2055],{"class":417}," ValidatesSelf",[363,2057,1236],{"class":384},[363,2059,2060],{"class":365,"line":395},[363,2061,392],{"emptyLinePlaceholder":391},[363,2063,2064,2066,2068,2071,2073,2076,2078],{"class":365,"line":423},[363,2065,454],{"class":453},[363,2067,458],{"class":457},[363,2069,2070],{"class":373}," DateRangeData",[363,2072,464],{"class":453},[363,2074,2075],{"class":467}," RequestData",[363,2077,802],{"class":384},[363,2079,2080],{"class":467}," ValidatesSelf\n",[363,2082,2083],{"class":365,"line":445},[363,2084,474],{"class":384},[363,2086,2087,2089,2091,2093],{"class":365,"line":450},[363,2088,480],{"class":453},[363,2090,483],{"class":457},[363,2092,487],{"class":486},[363,2094,490],{"class":384},[363,2096,2097,2099,2101,2103,2105,2108,2110,2112,2114,2116,2118,2120,2122,2125],{"class":365,"line":471},[363,2098,497],{"class":496},[363,2100,418],{"class":401},[363,2102,502],{"class":384},[363,2104,506],{"class":505},[363,2106,2107],{"class":509},"required|date:Y-m-d",[363,2109,506],{"class":505},[363,2111,515],{"class":384},[363,2113,1736],{"class":496},[363,2115,733],{"class":453},[363,2117,527],{"class":453},[363,2119,530],{"class":369},[363,2121,533],{"class":384},[363,2123,2124],{"class":496},"from",[363,2126,539],{"class":384},[363,2128,2129,2131,2133,2135,2137,2139,2141,2143,2145,2147,2149,2151,2153,2156],{"class":365,"line":477},[363,2130,497],{"class":496},[363,2132,418],{"class":401},[363,2134,502],{"class":384},[363,2136,506],{"class":505},[363,2138,2107],{"class":509},[363,2140,506],{"class":505},[363,2142,515],{"class":384},[363,2144,1736],{"class":496},[363,2146,733],{"class":453},[363,2148,527],{"class":453},[363,2150,530],{"class":369},[363,2152,533],{"class":384},[363,2154,2155],{"class":496},"to",[363,2157,539],{"class":384},[363,2159,2160,2162],{"class":365,"line":493},[363,2161,690],{"class":384},[363,2163,693],{"class":384},[363,2165,2166],{"class":365,"line":521},[363,2167,392],{"emptyLinePlaceholder":391},[363,2169,2170,2172,2174,2177,2180,2182],{"class":365,"line":542},[363,2171,480],{"class":453},[363,2173,483],{"class":457},[363,2175,2176],{"class":738}," validate",[363,2178,2179],{"class":384},"()",[363,2181,754],{"class":622},[363,2183,2184],{"class":369}," array\n",[363,2186,2187],{"class":365,"line":547},[363,2188,2189],{"class":384},"    {\n",[363,2191,2192,2196,2200,2202,2205,2208,2210,2212],{"class":365,"line":567},[363,2193,2195],{"class":2194},"sRxSC","        return",[363,2197,2199],{"class":2198},"sSBr1"," $this",[363,2201,787],{"class":622},[363,2203,2204],{"class":496},"from ",[363,2206,2207],{"class":622},">",[363,2209,2199],{"class":2198},[363,2211,787],{"class":622},[363,2213,2214],{"class":496},"to\n",[363,2216,2217,2220,2222,2224,2226,2228,2231,2233,2235,2238,2240],{"class":365,"line":583},[363,2218,2219],{"class":622},"            ?",[363,2221,805],{"class":384},[363,2223,506],{"class":505},[363,2225,2155],{"class":509},[363,2227,506],{"class":505},[363,2229,2230],{"class":622}," =>",[363,2232,805],{"class":384},[363,2234,506],{"class":505},[363,2236,2237],{"class":509},"The end date must be after the start date.",[363,2239,506],{"class":505},[363,2241,2242],{"class":384},"]]\n",[363,2244,2245,2248],{"class":365,"line":588},[363,2246,2247],{"class":622},"            :",[363,2249,2250],{"class":384}," [];\n",[363,2252,2253],{"class":365,"line":608},[363,2254,2255],{"class":384},"    }\n",[363,2257,2258],{"class":365,"line":636},[363,2259,699],{"class":384},[289,2261,2262],{},"The errors come back in the same 422 envelope.",[992,2264,2267],{"color":2265,"icon":2266,"variant":996},"info","i-tabler-info-circle",[998,2268,2269],{"v-slot:description":359},[289,2270,2271,2272,2274,2275,2278,2279,2282],{},"Use either a ",[305,2273,347],{}," parameter or ",[305,2276,2277],{},"#[Validate]"," + the ",[305,2280,2281],{},"validate"," middleware for a route's body, not both. The middleware runs first and can reject the request before the DTO is built.",[338,2284,2286],{"id":2285},"response-dtos","Response DTOs",[289,2288,2289,2290,2293,2294,2296,2297,2299],{},"A response DTO implements the ",[305,2291,2292],{},"ResponseData"," marker interface. Its ",[300,2295,733],{}," properties become the ",[305,2298,749],{}," payload:",[354,2301,2303],{"className":356,"code":2302,"language":358,"meta":359,"style":359},"namespace App\\DTOs;\n\nuse App\\Enums\\PostStatus;\nuse Glueful\\Http\\Contracts\\ResponseData;\n\nfinal class PostData implements ResponseData\n{\n    public function __construct(\n        public readonly string $uuid,\n        public readonly string $title,\n        public readonly PostStatus $status,\n        public readonly AuthorData $author,          // another ResponseData\n        public readonly \\DateTimeImmutable $createdAt,\n    ) {}\n}\n",[305,2304,2305,2317,2321,2339,2360,2364,2378,2382,2392,2406,2420,2436,2455,2474,2480],{"__ignoreMap":359},[363,2306,2307,2309,2311,2313,2315],{"class":365,"line":366},[363,2308,370],{"class":369},[363,2310,374],{"class":373},[363,2312,378],{"class":377},[363,2314,381],{"class":373},[363,2316,385],{"class":384},[363,2318,2319],{"class":365,"line":388},[363,2320,392],{"emptyLinePlaceholder":391},[363,2322,2323,2325,2327,2329,2332,2334,2337],{"class":365,"line":395},[363,2324,398],{"class":369},[363,2326,374],{"class":401},[363,2328,378],{"class":405},[363,2330,2331],{"class":401},"Enums",[363,2333,378],{"class":405},[363,2335,2336],{"class":417},"PostStatus",[363,2338,385],{"class":384},[363,2340,2341,2343,2345,2347,2350,2352,2354,2356,2358],{"class":365,"line":423},[363,2342,398],{"class":369},[363,2344,402],{"class":401},[363,2346,378],{"class":405},[363,2348,2349],{"class":401},"Http",[363,2351,378],{"class":405},[363,2353,436],{"class":401},[363,2355,378],{"class":405},[363,2357,2292],{"class":417},[363,2359,385],{"class":384},[363,2361,2362],{"class":365,"line":445},[363,2363,392],{"emptyLinePlaceholder":391},[363,2365,2366,2368,2370,2373,2375],{"class":365,"line":450},[363,2367,454],{"class":453},[363,2369,458],{"class":457},[363,2371,2372],{"class":373}," PostData",[363,2374,464],{"class":453},[363,2376,2377],{"class":467}," ResponseData\n",[363,2379,2380],{"class":365,"line":471},[363,2381,474],{"class":384},[363,2383,2384,2386,2388,2390],{"class":365,"line":477},[363,2385,480],{"class":453},[363,2387,483],{"class":457},[363,2389,487],{"class":486},[363,2391,490],{"class":384},[363,2393,2394,2396,2398,2400,2402,2404],{"class":365,"line":493},[363,2395,524],{"class":453},[363,2397,527],{"class":453},[363,2399,530],{"class":369},[363,2401,533],{"class":384},[363,2403,1326],{"class":496},[363,2405,539],{"class":384},[363,2407,2408,2410,2412,2414,2416,2418],{"class":365,"line":521},[363,2409,524],{"class":453},[363,2411,527],{"class":453},[363,2413,530],{"class":369},[363,2415,533],{"class":384},[363,2417,536],{"class":496},[363,2419,539],{"class":384},[363,2421,2422,2424,2426,2429,2431,2434],{"class":365,"line":542},[363,2423,524],{"class":453},[363,2425,527],{"class":453},[363,2427,2428],{"class":744}," PostStatus",[363,2430,533],{"class":384},[363,2432,2433],{"class":496},"status",[363,2435,539],{"class":384},[363,2437,2438,2440,2442,2445,2447,2450,2452],{"class":365,"line":547},[363,2439,524],{"class":453},[363,2441,527],{"class":453},[363,2443,2444],{"class":744}," AuthorData",[363,2446,533],{"class":384},[363,2448,2449],{"class":496},"author",[363,2451,802],{"class":384},[363,2453,2454],{"class":766},"          // another ResponseData\n",[363,2456,2457,2459,2461,2464,2467,2469,2472],{"class":365,"line":567},[363,2458,524],{"class":453},[363,2460,527],{"class":453},[363,2462,2463],{"class":1040}," \\",[363,2465,2466],{"class":744},"DateTimeImmutable",[363,2468,533],{"class":384},[363,2470,2471],{"class":496},"createdAt",[363,2473,539],{"class":384},[363,2475,2476,2478],{"class":365,"line":583},[363,2477,690],{"class":384},[363,2479,693],{"class":384},[363,2481,2482],{"class":365,"line":588},[363,2483,699],{"class":384},[354,2485,2487],{"className":356,"code":2486,"language":358,"meta":359,"style":359},"public function show(string $uuid): PostData\n{\n    $post = Post::query($this->context)->with('author')->where('uuid', $uuid)->firstOrFail();\n\n    return new PostData(\n        uuid: $post->uuid,\n        title: $post->title,\n        status: PostStatus::from($post->status),\n        author: new AuthorData($post->author->uuid, $post->author->name),\n        createdAt: $post->created_at,          // DateTimeImmutable via the model's 'datetime' cast\n    );\n}\n",[305,2488,2489,2513,2517,2590,2594,2606,2623,2640,2665,2705,2726,2731],{"__ignoreMap":359},[363,2490,2491,2493,2495,2498,2500,2502,2504,2506,2508,2510],{"class":365,"line":366},[363,2492,733],{"class":453},[363,2494,483],{"class":457},[363,2496,2497],{"class":738}," show",[363,2499,502],{"class":384},[363,2501,671],{"class":369},[363,2503,533],{"class":384},[363,2505,1326],{"class":496},[363,2507,515],{"class":384},[363,2509,754],{"class":622},[363,2511,2512],{"class":744}," PostData\n",[363,2514,2515],{"class":365,"line":388},[363,2516,474],{"class":384},[363,2518,2519,2522,2525,2527,2530,2532,2535,2537,2539,2541,2544,2546,2548,2551,2553,2555,2557,2559,2561,2563,2566,2568,2570,2572,2574,2576,2578,2580,2582,2584,2587],{"class":365,"line":395},[363,2520,2521],{"class":384},"    $",[363,2523,2524],{"class":496},"post ",[363,2526,623],{"class":622},[363,2528,2529],{"class":744}," Post",[363,2531,811],{"class":622},[363,2533,2534],{"class":738},"query",[363,2536,502],{"class":384},[363,2538,2000],{"class":2198},[363,2540,787],{"class":622},[363,2542,2543],{"class":496},"context",[363,2545,515],{"class":384},[363,2547,787],{"class":622},[363,2549,2550],{"class":738},"with",[363,2552,502],{"class":384},[363,2554,506],{"class":505},[363,2556,2449],{"class":509},[363,2558,506],{"class":505},[363,2560,515],{"class":384},[363,2562,787],{"class":622},[363,2564,2565],{"class":738},"where",[363,2567,502],{"class":384},[363,2569,506],{"class":505},[363,2571,1326],{"class":509},[363,2573,506],{"class":505},[363,2575,802],{"class":384},[363,2577,533],{"class":384},[363,2579,1326],{"class":496},[363,2581,515],{"class":384},[363,2583,787],{"class":622},[363,2585,2586],{"class":738},"firstOrFail",[363,2588,2589],{"class":384},"();\n",[363,2591,2592],{"class":365,"line":423},[363,2593,392],{"emptyLinePlaceholder":391},[363,2595,2596,2599,2602,2604],{"class":365,"line":445},[363,2597,2598],{"class":2194},"    return",[363,2600,2601],{"class":369}," new",[363,2603,2372],{"class":744},[363,2605,490],{"class":384},[363,2607,2608,2611,2613,2615,2617,2619,2621],{"class":365,"line":450},[363,2609,2610],{"class":1299},"        uuid",[363,2612,754],{"class":384},[363,2614,533],{"class":384},[363,2616,790],{"class":496},[363,2618,787],{"class":622},[363,2620,1326],{"class":496},[363,2622,539],{"class":384},[363,2624,2625,2628,2630,2632,2634,2636,2638],{"class":365,"line":471},[363,2626,2627],{"class":1299},"        title",[363,2629,754],{"class":384},[363,2631,533],{"class":384},[363,2633,790],{"class":496},[363,2635,787],{"class":622},[363,2637,536],{"class":496},[363,2639,539],{"class":384},[363,2641,2642,2645,2647,2649,2651,2653,2656,2658,2660,2662],{"class":365,"line":477},[363,2643,2644],{"class":1299},"        status",[363,2646,754],{"class":384},[363,2648,2428],{"class":744},[363,2650,811],{"class":622},[363,2652,2124],{"class":738},[363,2654,2655],{"class":384},"($",[363,2657,790],{"class":496},[363,2659,787],{"class":622},[363,2661,2433],{"class":496},[363,2663,2664],{"class":384},"),\n",[363,2666,2667,2670,2672,2674,2676,2678,2680,2682,2684,2686,2688,2690,2692,2694,2696,2698,2700,2703],{"class":365,"line":493},[363,2668,2669],{"class":1299},"        author",[363,2671,754],{"class":384},[363,2673,2601],{"class":369},[363,2675,2444],{"class":744},[363,2677,2655],{"class":384},[363,2679,790],{"class":496},[363,2681,787],{"class":622},[363,2683,2449],{"class":496},[363,2685,787],{"class":622},[363,2687,1326],{"class":496},[363,2689,802],{"class":384},[363,2691,533],{"class":384},[363,2693,790],{"class":496},[363,2695,787],{"class":622},[363,2697,2449],{"class":496},[363,2699,787],{"class":622},[363,2701,2702],{"class":496},"name",[363,2704,2664],{"class":384},[363,2706,2707,2710,2712,2714,2716,2718,2721,2723],{"class":365,"line":521},[363,2708,2709],{"class":1299},"        createdAt",[363,2711,754],{"class":384},[363,2713,533],{"class":384},[363,2715,790],{"class":496},[363,2717,787],{"class":622},[363,2719,2720],{"class":496},"created_at",[363,2722,802],{"class":384},[363,2724,2725],{"class":766},"          // DateTimeImmutable via the model's 'datetime' cast\n",[363,2727,2728],{"class":365,"line":542},[363,2729,2730],{"class":384},"    );\n",[363,2732,2733],{"class":365,"line":547},[363,2734,699],{"class":384},[354,2736,2738],{"className":1027,"code":2737,"language":1029,"meta":359,"style":359},"{\n  \"success\": true,\n  \"message\": \"Success\",\n  \"data\": {\n    \"uuid\": \"018e4c12-...\",\n    \"title\": \"Hello\",\n    \"status\": \"published\",\n    \"author\": { \"uuid\": \"018e3a00-...\", \"name\": \"Alice\" },\n    \"createdAt\": \"2026-06-14T09:00:00+00:00\"\n  }\n}\n",[305,2739,2740,2744,2759,2778,2790,2809,2828,2847,2895,2913,2917],{"__ignoreMap":359},[363,2741,2742],{"class":365,"line":366},[363,2743,474],{"class":384},[363,2745,2746,2748,2750,2752,2754,2757],{"class":365,"line":388},[363,2747,1041],{"class":1040},[363,2749,1045],{"class":1044},[363,2751,1048],{"class":1040},[363,2753,754],{"class":384},[363,2755,2756],{"class":681}," true",[363,2758,539],{"class":384},[363,2760,2761,2763,2765,2767,2769,2771,2774,2776],{"class":365,"line":395},[363,2762,1041],{"class":1040},[363,2764,1062],{"class":1044},[363,2766,1048],{"class":1040},[363,2768,754],{"class":384},[363,2770,1070],{"class":1069},[363,2772,2773],{"class":1073},"Success",[363,2775,1048],{"class":1069},[363,2777,539],{"class":384},[363,2779,2780,2782,2784,2786,2788],{"class":365,"line":423},[363,2781,1041],{"class":1040},[363,2783,749],{"class":1044},[363,2785,1048],{"class":1040},[363,2787,754],{"class":384},[363,2789,1092],{"class":384},[363,2791,2792,2794,2796,2798,2800,2802,2805,2807],{"class":365,"line":445},[363,2793,1097],{"class":1040},[363,2795,1326],{"class":744},[363,2797,1048],{"class":1040},[363,2799,754],{"class":384},[363,2801,1070],{"class":1069},[363,2803,2804],{"class":1073},"018e4c12-...",[363,2806,1048],{"class":1069},[363,2808,539],{"class":384},[363,2810,2811,2813,2815,2817,2819,2821,2824,2826],{"class":365,"line":450},[363,2812,1097],{"class":1040},[363,2814,536],{"class":744},[363,2816,1048],{"class":1040},[363,2818,754],{"class":384},[363,2820,1070],{"class":1069},[363,2822,2823],{"class":1073},"Hello",[363,2825,1048],{"class":1069},[363,2827,539],{"class":384},[363,2829,2830,2832,2834,2836,2838,2840,2843,2845],{"class":365,"line":471},[363,2831,1097],{"class":1040},[363,2833,2433],{"class":744},[363,2835,1048],{"class":1040},[363,2837,754],{"class":384},[363,2839,1070],{"class":1069},[363,2841,2842],{"class":1073},"published",[363,2844,1048],{"class":1069},[363,2846,539],{"class":384},[363,2848,2849,2851,2853,2855,2857,2859,2861,2864,2866,2868,2870,2873,2875,2877,2879,2881,2883,2885,2887,2890,2892],{"class":365,"line":477},[363,2850,1097],{"class":1040},[363,2852,2449],{"class":744},[363,2854,1048],{"class":1040},[363,2856,754],{"class":384},[363,2858,1550],{"class":384},[363,2860,1070],{"class":1040},[363,2862,1326],{"class":2863},"sTC9v",[363,2865,1048],{"class":1040},[363,2867,754],{"class":384},[363,2869,1070],{"class":1069},[363,2871,2872],{"class":1073},"018e3a00-...",[363,2874,1048],{"class":1069},[363,2876,802],{"class":384},[363,2878,1070],{"class":1040},[363,2880,2702],{"class":2863},[363,2882,1048],{"class":1040},[363,2884,754],{"class":384},[363,2886,1070],{"class":1069},[363,2888,2889],{"class":1073},"Alice",[363,2891,1048],{"class":1069},[363,2893,2894],{"class":384}," },\n",[363,2896,2897,2899,2901,2903,2905,2907,2910],{"class":365,"line":493},[363,2898,1097],{"class":1040},[363,2900,2471],{"class":744},[363,2902,1048],{"class":1040},[363,2904,754],{"class":384},[363,2906,1070],{"class":1069},[363,2908,2909],{"class":1073},"2026-06-14T09:00:00+00:00",[363,2911,2912],{"class":1069},"\"\n",[363,2914,2915],{"class":365,"line":521},[363,2916,1163],{"class":384},[363,2918,2919],{"class":365,"line":542},[363,2920,699],{"class":384},[289,2922,2923,2926],{},[305,2924,2925],{},"Glueful\\Serialization\\ResponseDataSerializer"," maps each value:",[2928,2929,2930,2943],"table",{},[2931,2932,2933],"thead",{},[2934,2935,2936,2940],"tr",{},[2937,2938,2939],"th",{},"Value",[2937,2941,2942],{},"Serialized as",[2944,2945,2946,2958,2968,2978,2991,3001,3008],"tbody",{},[2934,2947,2948,2955],{},[2949,2950,2951,2952],"td",{},"scalar / ",[305,2953,2954],{},"null",[2949,2956,2957],{},"as-is",[2934,2959,2960,2963],{},[2949,2961,2962],{},"backed enum",[2949,2964,2965],{},[305,2966,2967],{},"->value",[2934,2969,2970,2973],{},[2949,2971,2972],{},"pure enum",[2949,2974,2975],{},[305,2976,2977],{},"->name",[2934,2979,2980,2985],{},[2949,2981,2982],{},[305,2983,2984],{},"DateTimeInterface",[2949,2986,2987,2988,515],{},"ISO-8601 (",[305,2989,2990],{},"format('c')",[2934,2992,2993,2998],{},[2949,2994,2995,2996],{},"nested ",[305,2997,2292],{},[2949,2999,3000],{},"recursed",[2934,3002,3003,3005],{},[2949,3004,1618],{},[2949,3006,3007],{},"element-wise, using the same rules",[2934,3009,3010,3013],{},[2949,3011,3012],{},"other object",[2949,3014,3015],{},"its public properties, mapped recursively",[289,3017,3018,3019,3021,3022,3024,3025,312],{},"Uninitialized typed properties are skipped. Property names are kept as written (",[305,3020,2471],{}," stays ",[305,3023,2471],{},"). Self-references and nesting deeper than 5 levels render as ",[305,3026,2954],{},[289,3028,3029,3030,3033],{},"A DTO can control its own shape with a ",[305,3031,3032],{},"toArray(): array"," method. The serializer then uses its result verbatim, but the OpenAPI schema still reflects the public properties, so the two can drift.",[289,3035,3036,3037,312],{},"Generate a response DTO with ",[305,3038,3039],{},"php glueful scaffold:dto PostData --response",[854,3041,3043],{"id":3042},"status-and-message","Status and Message",[289,3045,3046,3049,3050,3053],{},[305,3047,3048],{},"#[ResponseStatus]"," sets a 2xx success status. A non-2xx value throws ",[305,3051,3052],{},"InvalidArgumentException"," when the attribute is read:",[354,3055,3057],{"className":356,"code":3056,"language":358,"meta":359,"style":359},"use Glueful\\Routing\\Attributes\\ResponseStatus;\n\n#[ResponseStatus(201)]\npublic function store(CreatePostData $data): PostData\n{\n    // → 201 {\"success\": true, \"message\": \"Created successfully\", \"data\": {...}}\n}\n",[305,3058,3059,3080,3084,3101,3123,3127,3132],{"__ignoreMap":359},[363,3060,3061,3063,3065,3067,3069,3071,3073,3075,3078],{"class":365,"line":366},[363,3062,398],{"class":369},[363,3064,402],{"class":401},[363,3066,378],{"class":405},[363,3068,29],{"class":401},[363,3070,378],{"class":405},[363,3072,412],{"class":401},[363,3074,378],{"class":405},[363,3076,3077],{"class":417},"ResponseStatus",[363,3079,385],{"class":384},[363,3081,3082],{"class":365,"line":388},[363,3083,392],{"emptyLinePlaceholder":391},[363,3085,3086,3089,3091,3093,3097,3099],{"class":365,"line":395},[363,3087,3088],{"class":496},"#[",[363,3090,3077],{"class":401},[363,3092,502],{"class":384},[363,3094,3096],{"class":3095},"sYThS","201",[363,3098,515],{"class":384},[363,3100,518],{"class":496},[363,3102,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121],{"class":365,"line":423},[363,3104,733],{"class":453},[363,3106,483],{"class":457},[363,3108,739],{"class":738},[363,3110,502],{"class":384},[363,3112,722],{"class":744},[363,3114,533],{"class":384},[363,3116,749],{"class":496},[363,3118,515],{"class":384},[363,3120,754],{"class":622},[363,3122,2512],{"class":744},[363,3124,3125],{"class":365,"line":445},[363,3126,474],{"class":384},[363,3128,3129],{"class":365,"line":450},[363,3130,3131],{"class":766},"    // → 201 {\"success\": true, \"message\": \"Created successfully\", \"data\": {...}}\n",[363,3133,3134],{"class":365,"line":471},[363,3135,699],{"class":384},[289,3137,3138,3139,3141,3142,3145,3146,3149,3150,754],{},"The default message is ",[305,3140,2773],{}," (or ",[305,3143,3144],{},"Created successfully"," for 201). To supply your own, implement ",[305,3147,3148],{},"Glueful\\Http\\Contracts\\HasResponseMessage"," and keep the message in a private property so it doesn't leak into ",[305,3151,749],{},[354,3153,3155],{"className":356,"code":3154,"language":358,"meta":359,"style":359},"use Glueful\\Http\\Contracts\\{HasResponseMessage, ResponseData};\n\nfinal class PasswordResetData implements ResponseData, HasResponseMessage\n{\n    public function __construct(\n        public readonly string $email,\n        private readonly string $message = 'Reset link sent',\n    ) {}\n\n    public function responseMessage(): string\n    {\n        return $this->message;\n    }\n}\n",[305,3156,3157,3185,3189,3207,3211,3221,3235,3260,3266,3270,3286,3290,3302,3306],{"__ignoreMap":359},[363,3158,3159,3161,3163,3165,3167,3169,3171,3173,3175,3178,3180,3183],{"class":365,"line":366},[363,3160,398],{"class":369},[363,3162,402],{"class":401},[363,3164,378],{"class":405},[363,3166,2349],{"class":401},[363,3168,378],{"class":405},[363,3170,436],{"class":401},[363,3172,378],{"class":405},[363,3174,1220],{"class":384},[363,3176,3177],{"class":417},"HasResponseMessage",[363,3179,802],{"class":384},[363,3181,3182],{"class":417}," ResponseData",[363,3184,1236],{"class":384},[363,3186,3187],{"class":365,"line":388},[363,3188,392],{"emptyLinePlaceholder":391},[363,3190,3191,3193,3195,3198,3200,3202,3204],{"class":365,"line":395},[363,3192,454],{"class":453},[363,3194,458],{"class":457},[363,3196,3197],{"class":373}," PasswordResetData",[363,3199,464],{"class":453},[363,3201,3182],{"class":467},[363,3203,802],{"class":384},[363,3205,3206],{"class":467}," HasResponseMessage\n",[363,3208,3209],{"class":365,"line":423},[363,3210,474],{"class":384},[363,3212,3213,3215,3217,3219],{"class":365,"line":445},[363,3214,480],{"class":453},[363,3216,483],{"class":457},[363,3218,487],{"class":486},[363,3220,490],{"class":384},[363,3222,3223,3225,3227,3229,3231,3233],{"class":365,"line":450},[363,3224,524],{"class":453},[363,3226,527],{"class":453},[363,3228,530],{"class":369},[363,3230,533],{"class":384},[363,3232,652],{"class":496},[363,3234,539],{"class":384},[363,3236,3237,3240,3242,3244,3246,3249,3251,3253,3256,3258],{"class":365,"line":471},[363,3238,3239],{"class":453},"        private",[363,3241,527],{"class":453},[363,3243,530],{"class":369},[363,3245,533],{"class":384},[363,3247,3248],{"class":496},"message ",[363,3250,623],{"class":622},[363,3252,626],{"class":505},[363,3254,3255],{"class":509},"Reset link sent",[363,3257,506],{"class":505},[363,3259,539],{"class":384},[363,3261,3262,3264],{"class":365,"line":477},[363,3263,690],{"class":384},[363,3265,693],{"class":384},[363,3267,3268],{"class":365,"line":493},[363,3269,392],{"emptyLinePlaceholder":391},[363,3271,3272,3274,3276,3279,3281,3283],{"class":365,"line":521},[363,3273,480],{"class":453},[363,3275,483],{"class":457},[363,3277,3278],{"class":738}," responseMessage",[363,3280,2179],{"class":384},[363,3282,754],{"class":622},[363,3284,3285],{"class":369}," string\n",[363,3287,3288],{"class":365,"line":542},[363,3289,2189],{"class":384},[363,3291,3292,3294,3296,3298,3300],{"class":365,"line":547},[363,3293,2195],{"class":2194},[363,3295,2199],{"class":2198},[363,3297,787],{"class":622},[363,3299,1062],{"class":496},[363,3301,385],{"class":384},[363,3303,3304],{"class":365,"line":567},[363,3305,2255],{"class":384},[363,3307,3308],{"class":365,"line":583},[363,3309,699],{"class":384},[338,3311,3313],{"id":3312},"collections-and-pagination","Collections and Pagination",[289,3315,3316,3317,3320,3321,3323],{},"Return ",[305,3318,3319],{},"Glueful\\Http\\Responses\\CollectionResponse"," for a list. Each ",[305,3322,2292],{}," item is serialized, and arrays and scalars pass through unchanged:",[354,3325,3327],{"className":356,"code":3326,"language":358,"meta":359,"style":359},"use Glueful\\Http\\Responses\\CollectionResponse;\n\n/** @return CollectionResponse\u003CPostData> */\npublic function index(): CollectionResponse\n{\n    $posts = Post::query($this->context)->with('author')->latest()->limit(50)->get();\n\n    return new CollectionResponse(\n        $posts->map(fn (Post $p) => PostData::fromModel($p))->all()\n    );\n}\n// → {\"success\": true, \"message\": \"Success\", \"data\": [ {...}, {...} ]}\n",[305,3328,3329,3351,3355,3377,3393,3397,3462,3466,3476,3529,3533,3537],{"__ignoreMap":359},[363,3330,3331,3333,3335,3337,3339,3341,3344,3346,3349],{"class":365,"line":366},[363,3332,398],{"class":369},[363,3334,402],{"class":401},[363,3336,378],{"class":405},[363,3338,2349],{"class":401},[363,3340,378],{"class":405},[363,3342,3343],{"class":401},"Responses",[363,3345,378],{"class":405},[363,3347,3348],{"class":417},"CollectionResponse",[363,3350,385],{"class":384},[363,3352,3353],{"class":365,"line":388},[363,3354,392],{"emptyLinePlaceholder":391},[363,3356,3357,3360,3364,3368,3371,3374],{"class":365,"line":395},[363,3358,3359],{"class":766},"/** ",[363,3361,3363],{"class":3362},"s41CE","@return",[363,3365,3367],{"class":3366},"s6MXs"," CollectionResponse",[363,3369,3370],{"class":766},"\u003C",[363,3372,3373],{"class":3366},"PostData",[363,3375,3376],{"class":766},"> */\n",[363,3378,3379,3381,3383,3386,3388,3390],{"class":365,"line":423},[363,3380,733],{"class":453},[363,3382,483],{"class":457},[363,3384,3385],{"class":738}," index",[363,3387,2179],{"class":384},[363,3389,754],{"class":622},[363,3391,3392],{"class":744}," CollectionResponse\n",[363,3394,3395],{"class":365,"line":445},[363,3396,474],{"class":384},[363,3398,3399,3401,3404,3406,3408,3410,3412,3414,3416,3418,3420,3422,3424,3426,3428,3430,3432,3434,3436,3438,3441,3443,3445,3448,3450,3453,3455,3457,3460],{"class":365,"line":450},[363,3400,2521],{"class":384},[363,3402,3403],{"class":496},"posts ",[363,3405,623],{"class":622},[363,3407,2529],{"class":744},[363,3409,811],{"class":622},[363,3411,2534],{"class":738},[363,3413,502],{"class":384},[363,3415,2000],{"class":2198},[363,3417,787],{"class":622},[363,3419,2543],{"class":496},[363,3421,515],{"class":384},[363,3423,787],{"class":622},[363,3425,2550],{"class":738},[363,3427,502],{"class":384},[363,3429,506],{"class":505},[363,3431,2449],{"class":509},[363,3433,506],{"class":505},[363,3435,515],{"class":384},[363,3437,787],{"class":622},[363,3439,3440],{"class":738},"latest",[363,3442,2179],{"class":384},[363,3444,787],{"class":622},[363,3446,3447],{"class":738},"limit",[363,3449,502],{"class":384},[363,3451,3452],{"class":3095},"50",[363,3454,515],{"class":384},[363,3456,787],{"class":622},[363,3458,3459],{"class":738},"get",[363,3461,2589],{"class":384},[363,3463,3464],{"class":365,"line":471},[363,3465,392],{"emptyLinePlaceholder":391},[363,3467,3468,3470,3472,3474],{"class":365,"line":477},[363,3469,2598],{"class":2194},[363,3471,2601],{"class":369},[363,3473,3367],{"class":744},[363,3475,490],{"class":384},[363,3477,3478,3481,3484,3486,3489,3491,3494,3496,3499,3501,3503,3505,3507,3509,3511,3514,3516,3518,3521,3523,3526],{"class":365,"line":493},[363,3479,3480],{"class":384},"        $",[363,3482,3483],{"class":496},"posts",[363,3485,787],{"class":622},[363,3487,3488],{"class":738},"map",[363,3490,502],{"class":384},[363,3492,3493],{"class":457},"fn",[363,3495,303],{"class":384},[363,3497,3498],{"class":744},"Post",[363,3500,533],{"class":384},[363,3502,289],{"class":496},[363,3504,515],{"class":384},[363,3506,2230],{"class":384},[363,3508,2372],{"class":744},[363,3510,811],{"class":622},[363,3512,3513],{"class":738},"fromModel",[363,3515,2655],{"class":384},[363,3517,289],{"class":496},[363,3519,3520],{"class":384},"))",[363,3522,787],{"class":622},[363,3524,3525],{"class":738},"all",[363,3527,3528],{"class":384},"()\n",[363,3530,3531],{"class":365,"line":521},[363,3532,2730],{"class":384},[363,3534,3535],{"class":365,"line":542},[363,3536,699],{"class":384},[363,3538,3539],{"class":365,"line":547},[363,3540,3541],{"class":766},"// → {\"success\": true, \"message\": \"Success\", \"data\": [ {...}, {...} ]}\n",[289,3543,3544,3546,3547,3549],{},[305,3545,3048],{}," applies to a ",[305,3548,3348],{}," too.",[289,3551,3316,3552,3555,3556,3559,3560,863,3563,971,3566,754],{},[305,3553,3554],{},"Glueful\\Http\\Responses\\PaginatedResponse"," for a page. Its constructor takes ",[305,3557,3558],{},"($items, $page, $perPage, $total)"," and rejects ",[305,3561,3562],{},"page \u003C 1",[305,3564,3565],{},"perPage \u003C 1",[305,3567,3568],{},"total \u003C 0",[354,3570,3572],{"className":356,"code":3571,"language":358,"meta":359,"style":359},"use Glueful\\Http\\Responses\\PaginatedResponse;\nuse Glueful\\Validation\\Attributes\\{FromQuery, Rule};\nuse Glueful\\Validation\\Contracts\\RequestData;\n\nfinal class ListPostsData implements RequestData\n{\n    public function __construct(\n        #[FromQuery] #[Rule('numeric')] public readonly int $page = 1,\n        #[FromQuery] #[Rule('numeric')] public readonly int $per_page = 20,\n    ) {}\n}\n\n/** @return PaginatedResponse\u003CPostData> */\npublic function index(ListPostsData $q): PaginatedResponse\n{\n    $page = Post::query($this->context)\n        ->where('status', 'published')\n        ->with('author')\n        ->latest()\n        ->paginate($q->page, $q->per_page);   // 'data' is a Collection of models\n\n    return new PaginatedResponse(\n        $page['data']->map(fn (Post $p) => PostData::fromModel($p))->all(),\n        $q->page,\n        $q->per_page,\n        $page['total'],\n    );\n}\n",[305,3573,3574,3595,3621,3641,3645,3658,3662,3672,3714,3754,3760,3764,3768,3783,3808,3812,3837,3862,3878,3886,3919,3923,3934,3992,4005,4018,4036,4041],{"__ignoreMap":359},[363,3575,3576,3578,3580,3582,3584,3586,3588,3590,3593],{"class":365,"line":366},[363,3577,398],{"class":369},[363,3579,402],{"class":401},[363,3581,378],{"class":405},[363,3583,2349],{"class":401},[363,3585,378],{"class":405},[363,3587,3343],{"class":401},[363,3589,378],{"class":405},[363,3591,3592],{"class":417},"PaginatedResponse",[363,3594,385],{"class":384},[363,3596,3597,3599,3601,3603,3605,3607,3609,3611,3613,3615,3617,3619],{"class":365,"line":388},[363,3598,398],{"class":369},[363,3600,402],{"class":401},[363,3602,378],{"class":405},[363,3604,57],{"class":401},[363,3606,378],{"class":405},[363,3608,412],{"class":401},[363,3610,378],{"class":405},[363,3612,1220],{"class":384},[363,3614,1223],{"class":417},[363,3616,802],{"class":384},[363,3618,1233],{"class":417},[363,3620,1236],{"class":384},[363,3622,3623,3625,3627,3629,3631,3633,3635,3637,3639],{"class":365,"line":395},[363,3624,398],{"class":369},[363,3626,402],{"class":401},[363,3628,378],{"class":405},[363,3630,57],{"class":401},[363,3632,378],{"class":405},[363,3634,436],{"class":401},[363,3636,378],{"class":405},[363,3638,347],{"class":417},[363,3640,385],{"class":384},[363,3642,3643],{"class":365,"line":423},[363,3644,392],{"emptyLinePlaceholder":391},[363,3646,3647,3649,3651,3654,3656],{"class":365,"line":445},[363,3648,454],{"class":453},[363,3650,458],{"class":457},[363,3652,3653],{"class":373}," ListPostsData",[363,3655,464],{"class":453},[363,3657,468],{"class":467},[363,3659,3660],{"class":365,"line":450},[363,3661,474],{"class":384},[363,3663,3664,3666,3668,3670],{"class":365,"line":471},[363,3665,480],{"class":453},[363,3667,483],{"class":457},[363,3669,487],{"class":486},[363,3671,490],{"class":384},[363,3673,3674,3676,3678,3681,3683,3685,3687,3690,3692,3694,3696,3698,3700,3702,3704,3707,3709,3712],{"class":365,"line":477},[363,3675,497],{"class":496},[363,3677,1223],{"class":401},[363,3679,3680],{"class":496},"] #[",[363,3682,418],{"class":401},[363,3684,502],{"class":384},[363,3686,506],{"class":505},[363,3688,3689],{"class":509},"numeric",[363,3691,506],{"class":505},[363,3693,515],{"class":384},[363,3695,1736],{"class":496},[363,3697,733],{"class":453},[363,3699,527],{"class":453},[363,3701,1775],{"class":369},[363,3703,533],{"class":384},[363,3705,3706],{"class":496},"page ",[363,3708,623],{"class":622},[363,3710,3711],{"class":3095}," 1",[363,3713,539],{"class":384},[363,3715,3716,3718,3720,3722,3724,3726,3728,3730,3732,3734,3736,3738,3740,3742,3744,3747,3749,3752],{"class":365,"line":493},[363,3717,497],{"class":496},[363,3719,1223],{"class":401},[363,3721,3680],{"class":496},[363,3723,418],{"class":401},[363,3725,502],{"class":384},[363,3727,506],{"class":505},[363,3729,3689],{"class":509},[363,3731,506],{"class":505},[363,3733,515],{"class":384},[363,3735,1736],{"class":496},[363,3737,733],{"class":453},[363,3739,527],{"class":453},[363,3741,1775],{"class":369},[363,3743,533],{"class":384},[363,3745,3746],{"class":496},"per_page ",[363,3748,623],{"class":622},[363,3750,3751],{"class":3095}," 20",[363,3753,539],{"class":384},[363,3755,3756,3758],{"class":365,"line":521},[363,3757,690],{"class":384},[363,3759,693],{"class":384},[363,3761,3762],{"class":365,"line":542},[363,3763,699],{"class":384},[363,3765,3766],{"class":365,"line":547},[363,3767,392],{"emptyLinePlaceholder":391},[363,3769,3770,3772,3774,3777,3779,3781],{"class":365,"line":567},[363,3771,3359],{"class":766},[363,3773,3363],{"class":3362},[363,3775,3776],{"class":3366}," PaginatedResponse",[363,3778,3370],{"class":766},[363,3780,3373],{"class":3366},[363,3782,3376],{"class":766},[363,3784,3785,3787,3789,3791,3793,3796,3798,3801,3803,3805],{"class":365,"line":583},[363,3786,733],{"class":453},[363,3788,483],{"class":457},[363,3790,3385],{"class":738},[363,3792,502],{"class":384},[363,3794,3795],{"class":744},"ListPostsData",[363,3797,533],{"class":384},[363,3799,3800],{"class":496},"q",[363,3802,515],{"class":384},[363,3804,754],{"class":622},[363,3806,3807],{"class":744}," PaginatedResponse\n",[363,3809,3810],{"class":365,"line":588},[363,3811,474],{"class":384},[363,3813,3814,3816,3818,3820,3822,3824,3826,3828,3830,3832,3834],{"class":365,"line":608},[363,3815,2521],{"class":384},[363,3817,3706],{"class":496},[363,3819,623],{"class":622},[363,3821,2529],{"class":744},[363,3823,811],{"class":622},[363,3825,2534],{"class":738},[363,3827,502],{"class":384},[363,3829,2000],{"class":2198},[363,3831,787],{"class":622},[363,3833,2543],{"class":496},[363,3835,3836],{"class":384},")\n",[363,3838,3839,3842,3844,3846,3848,3850,3852,3854,3856,3858,3860],{"class":365,"line":636},[363,3840,3841],{"class":622},"        ->",[363,3843,2565],{"class":738},[363,3845,502],{"class":384},[363,3847,506],{"class":505},[363,3849,2433],{"class":509},[363,3851,506],{"class":505},[363,3853,802],{"class":384},[363,3855,626],{"class":505},[363,3857,2842],{"class":509},[363,3859,506],{"class":505},[363,3861,3836],{"class":384},[363,3863,3864,3866,3868,3870,3872,3874,3876],{"class":365,"line":641},[363,3865,3841],{"class":622},[363,3867,2550],{"class":738},[363,3869,502],{"class":384},[363,3871,506],{"class":505},[363,3873,2449],{"class":509},[363,3875,506],{"class":505},[363,3877,3836],{"class":384},[363,3879,3880,3882,3884],{"class":365,"line":661},[363,3881,3841],{"class":622},[363,3883,3440],{"class":738},[363,3885,3528],{"class":384},[363,3887,3888,3890,3893,3895,3897,3899,3902,3904,3906,3908,3910,3913,3916],{"class":365,"line":687},[363,3889,3841],{"class":622},[363,3891,3892],{"class":738},"paginate",[363,3894,2655],{"class":384},[363,3896,3800],{"class":496},[363,3898,787],{"class":622},[363,3900,3901],{"class":496},"page",[363,3903,802],{"class":384},[363,3905,533],{"class":384},[363,3907,3800],{"class":496},[363,3909,787],{"class":622},[363,3911,3912],{"class":496},"per_page",[363,3914,3915],{"class":384},");",[363,3917,3918],{"class":766},"   // 'data' is a Collection of models\n",[363,3920,3921],{"class":365,"line":696},[363,3922,392],{"emptyLinePlaceholder":391},[363,3924,3926,3928,3930,3932],{"class":365,"line":3925},22,[363,3927,2598],{"class":2194},[363,3929,2601],{"class":369},[363,3931,3776],{"class":744},[363,3933,490],{"class":384},[363,3935,3937,3939,3941,3944,3946,3948,3950,3953,3955,3957,3959,3961,3963,3965,3967,3969,3971,3973,3975,3977,3979,3981,3983,3985,3987,3989],{"class":365,"line":3936},23,[363,3938,3480],{"class":384},[363,3940,3901],{"class":496},[363,3942,3943],{"class":384},"[",[363,3945,506],{"class":505},[363,3947,749],{"class":509},[363,3949,506],{"class":505},[363,3951,3952],{"class":384},"]",[363,3954,787],{"class":622},[363,3956,3488],{"class":738},[363,3958,502],{"class":384},[363,3960,3493],{"class":457},[363,3962,303],{"class":384},[363,3964,3498],{"class":744},[363,3966,533],{"class":384},[363,3968,289],{"class":496},[363,3970,515],{"class":384},[363,3972,2230],{"class":384},[363,3974,2372],{"class":744},[363,3976,811],{"class":622},[363,3978,3513],{"class":738},[363,3980,2655],{"class":384},[363,3982,289],{"class":496},[363,3984,3520],{"class":384},[363,3986,787],{"class":622},[363,3988,3525],{"class":738},[363,3990,3991],{"class":384},"(),\n",[363,3993,3995,3997,3999,4001,4003],{"class":365,"line":3994},24,[363,3996,3480],{"class":384},[363,3998,3800],{"class":496},[363,4000,787],{"class":622},[363,4002,3901],{"class":496},[363,4004,539],{"class":384},[363,4006,4008,4010,4012,4014,4016],{"class":365,"line":4007},25,[363,4009,3480],{"class":384},[363,4011,3800],{"class":496},[363,4013,787],{"class":622},[363,4015,3912],{"class":496},[363,4017,539],{"class":384},[363,4019,4021,4023,4025,4027,4029,4032,4034],{"class":365,"line":4020},26,[363,4022,3480],{"class":384},[363,4024,3901],{"class":496},[363,4026,3943],{"class":384},[363,4028,506],{"class":505},[363,4030,4031],{"class":509},"total",[363,4033,506],{"class":505},[363,4035,1115],{"class":384},[363,4037,4039],{"class":365,"line":4038},27,[363,4040,2730],{"class":384},[363,4042,4044],{"class":365,"line":4043},28,[363,4045,699],{"class":384},[354,4047,4049],{"className":1027,"code":4048,"language":1029,"meta":359,"style":359},"{\n  \"success\": true,\n  \"message\": \"Data retrieved successfully\",\n  \"data\": [ {...} ],\n  \"current_page\": 1,\n  \"per_page\": 20,\n  \"total\": 135,\n  \"total_pages\": 7,\n  \"has_next_page\": true,\n  \"has_previous_page\": false\n}\n",[305,4050,4051,4055,4069,4088,4112,4127,4141,4156,4172,4187,4201],{"__ignoreMap":359},[363,4052,4053],{"class":365,"line":366},[363,4054,474],{"class":384},[363,4056,4057,4059,4061,4063,4065,4067],{"class":365,"line":388},[363,4058,1041],{"class":1040},[363,4060,1045],{"class":1044},[363,4062,1048],{"class":1040},[363,4064,754],{"class":384},[363,4066,2756],{"class":681},[363,4068,539],{"class":384},[363,4070,4071,4073,4075,4077,4079,4081,4084,4086],{"class":365,"line":395},[363,4072,1041],{"class":1040},[363,4074,1062],{"class":1044},[363,4076,1048],{"class":1040},[363,4078,754],{"class":384},[363,4080,1070],{"class":1069},[363,4082,4083],{"class":1073},"Data retrieved successfully",[363,4085,1048],{"class":1069},[363,4087,539],{"class":384},[363,4089,4090,4092,4094,4096,4098,4100,4102,4106,4109],{"class":365,"line":423},[363,4091,1041],{"class":1040},[363,4093,749],{"class":1044},[363,4095,1048],{"class":1040},[363,4097,754],{"class":384},[363,4099,805],{"class":384},[363,4101,1550],{"class":384},[363,4103,4105],{"class":4104},"s4fT8","...",[363,4107,4108],{"class":384},"}",[363,4110,4111],{"class":384}," ],\n",[363,4113,4114,4116,4119,4121,4123,4125],{"class":365,"line":445},[363,4115,1041],{"class":1040},[363,4117,4118],{"class":1044},"current_page",[363,4120,1048],{"class":1040},[363,4122,754],{"class":384},[363,4124,3711],{"class":3095},[363,4126,539],{"class":384},[363,4128,4129,4131,4133,4135,4137,4139],{"class":365,"line":450},[363,4130,1041],{"class":1040},[363,4132,3912],{"class":1044},[363,4134,1048],{"class":1040},[363,4136,754],{"class":384},[363,4138,3751],{"class":3095},[363,4140,539],{"class":384},[363,4142,4143,4145,4147,4149,4151,4154],{"class":365,"line":471},[363,4144,1041],{"class":1040},[363,4146,4031],{"class":1044},[363,4148,1048],{"class":1040},[363,4150,754],{"class":384},[363,4152,4153],{"class":3095}," 135",[363,4155,539],{"class":384},[363,4157,4158,4160,4163,4165,4167,4170],{"class":365,"line":477},[363,4159,1041],{"class":1040},[363,4161,4162],{"class":1044},"total_pages",[363,4164,1048],{"class":1040},[363,4166,754],{"class":384},[363,4168,4169],{"class":3095}," 7",[363,4171,539],{"class":384},[363,4173,4174,4176,4179,4181,4183,4185],{"class":365,"line":493},[363,4175,1041],{"class":1040},[363,4177,4178],{"class":1044},"has_next_page",[363,4180,1048],{"class":1040},[363,4182,754],{"class":384},[363,4184,2756],{"class":681},[363,4186,539],{"class":384},[363,4188,4189,4191,4194,4196,4198],{"class":365,"line":521},[363,4190,1041],{"class":1040},[363,4192,4193],{"class":1044},"has_previous_page",[363,4195,1048],{"class":1040},[363,4197,754],{"class":384},[363,4199,4200],{"class":681}," false\n",[363,4202,4203],{"class":365,"line":542},[363,4204,699],{"class":384},[289,4206,4207,4208,4211,4212,4214],{},"A paginated response is always ",[305,4209,4210],{},"200",", and ",[305,4213,3048],{}," has no effect on it.",[289,4216,4217,4218,4221],{},"The ",[305,4219,4220],{},"@return CollectionResponse\u003CPostData>"," docblock is optional at runtime. The OpenAPI generator reads it to document the item schema.",[289,4223,502,4224,4227],{},[305,4225,4226],{},"PostData::fromModel()"," in these examples is your own static constructor. Mapping models into DTOs keeps the API contract independent of the table.)",[338,4229,4231],{"id":4230},"what-else-a-handler-can-return","What Else a Handler Can Return",[2928,4233,4234,4244],{},[2931,4235,4236],{},[2934,4237,4238,4241],{},[2937,4239,4240],{},"Return value",[2937,4242,4243],{},"Response",[2944,4245,4246,4260,4273,4282,4305,4314],{},[2934,4247,4248,4252],{},[2949,4249,4250],{},[305,4251,2292],{},[2949,4253,4254,4256,4257,4259],{},[305,4255,324],{}," at the ",[305,4258,3048],{}," status",[2934,4261,4262,4266],{},[2949,4263,4264],{},[305,4265,3348],{},[2949,4267,4268,4256,4271,4259],{},[305,4269,4270],{},"{success, message, data: [...]}",[305,4272,3048],{},[2934,4274,4275,4279],{},[2949,4276,4277],{},[305,4278,3592],{},[2949,4280,4281],{},"Flat pagination envelope, always 200",[2934,4283,4284,4295],{},[2949,4285,4286,863,4289,863,4292],{},[305,4287,4288],{},"JsonResource",[305,4290,4291],{},"ResourceCollection",[305,4293,4294],{},"PaginatedResourceResponse",[2949,4296,4297,4298,4301,4302,4304],{},"The resource's own ",[305,4299,4300],{},"toResponse()",", with ",[305,4303,3048],{}," passed through",[2934,4306,4307,4311],{},[2949,4308,298,4309],{},[305,4310,4243],{},[2949,4312,4313],{},"Unchanged",[2934,4315,4316,4319],{},[2949,4317,4318],{},"Other array or object",[2949,4320,4321,4322,4325],{},"Raw ",[305,4323,4324],{},"JsonResponse",", no envelope",[338,4327,4329],{"id":4328},"next-steps","Next Steps",[293,4331,4332,4342,4347,4355],{},[296,4333,4334,4336,4337,1569,4339],{},[330,4335,57],{"href":58},": every rule, custom rules, and ",[305,4338,2277],{},[305,4340,4341],{},"FormRequest",[296,4343,4344,4346],{},[330,4345,149],{"href":150},": how these types become the spec",[296,4348,4349,4351,4352,4354],{},[330,4350,45],{"href":46},": reading raw input and the ",[305,4353,4243],{}," helpers",[296,4356,4357,4359],{},[330,4358,65],{"href":66},": loading the data you map into response DTOs",[4361,4362,4363],"style",{},"html pre.shiki code .shWJe, html code.shiki .shWJe{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sKvfc, html code.shiki .sKvfc{--shiki-light:#E2931D;--shiki-light-text-decoration:inherit;--shiki-default:#6F42C1;--shiki-default-text-decoration:inherit;--shiki-dark:#B392F0;--shiki-dark-text-decoration:inherit;--shiki-sepia:#A6E22E;--shiki-sepia-text-decoration:underline}html pre.shiki code .sANao, html code.shiki .sANao{--shiki-light:#39ADB5;--shiki-light-text-decoration:inherit;--shiki-default:#6F42C1;--shiki-default-text-decoration:inherit;--shiki-dark:#B392F0;--shiki-dark-text-decoration:inherit;--shiki-sepia:#A6E22E;--shiki-sepia-text-decoration:underline}html pre.shiki code .swvn1, html code.shiki .swvn1{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .s91G_, html code.shiki .s91G_{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .sv8o3, html code.shiki .sv8o3{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .seZir, html code.shiki .seZir{--shiki-light:#90A4AE;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sTNss, html code.shiki .sTNss{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .srJo8, html code.shiki .srJo8{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sW3Pz, html code.shiki .sW3Pz{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-light-text-decoration:inherit;--shiki-default:#6F42C1;--shiki-default-font-style:inherit;--shiki-default-text-decoration:inherit;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit;--shiki-dark-text-decoration:inherit;--shiki-sepia:#A6E22E;--shiki-sepia-font-style:italic;--shiki-sepia-text-decoration:underline}html pre.shiki code .sMLJd, html code.shiki .sMLJd{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .ss--_, html code.shiki .ss--_{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .siCPE, html code.shiki .siCPE{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sLACW, html code.shiki .sLACW{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sGXK2, html code.shiki .sGXK2{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sMTiH, html code.shiki .sMTiH{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}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 .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sD0ED, html code.shiki .sD0ED{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s_MOj, html code.shiki .s_MOj{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sR7ES, html code.shiki .sR7ES{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .saDeg, html code.shiki .saDeg{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sEff5, html code.shiki .sEff5{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sh1VR, html code.shiki .sh1VR{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sINAO, html code.shiki .sINAO{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sQqfL, html code.shiki .sQqfL{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#F8F8F2}html pre.shiki code .sRxSC, html code.shiki .sRxSC{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sSBr1, html code.shiki .sSBr1{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sTC9v, html code.shiki .sTC9v{--shiki-light:#F76D47;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sYThS, html code.shiki .sYThS{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s41CE, html code.shiki .s41CE{--shiki-light:#F76D47;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .s6MXs, html code.shiki .s6MXs{--shiki-light:#E2931D;--shiki-light-font-style:italic;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s4fT8, html code.shiki .s4fT8{--shiki-light:#90A4AE;--shiki-light-font-style:inherit;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic;--shiki-sepia:#F44747;--shiki-sepia-font-style:inherit}",{"title":359,"searchDepth":366,"depth":388,"links":4365},[4366,4370,4371,4372,4373,4376,4377,4378],{"id":340,"depth":388,"text":341,"children":4367},[4368,4369],{"id":856,"depth":395,"text":857},{"id":1016,"depth":395,"text":1017},{"id":1186,"depth":388,"text":880},{"id":1611,"depth":388,"text":1612},{"id":1985,"depth":388,"text":1986},{"id":2285,"depth":388,"text":2286,"children":4374},[4375],{"id":3042,"depth":395,"text":3043},{"id":3312,"depth":388,"text":3313},{"id":4230,"depth":388,"text":4231},{"id":4328,"depth":388,"text":4329},"Declare request and response contracts as PHP classes. The router validates input before your handler runs, envelopes output after it returns, and the same types drive the OpenAPI spec.","md",null,{},{"title":33,"description":4379},"J3BzFgILiY0og1ELnp1-3MICodl_j3UCARYZ5SyoivQ",[4386,4388],{"title":29,"path":30,"stem":31,"description":4387,"children":-1},"Define routes with closures, controllers, groups, and attributes",{"title":37,"path":38,"stem":39,"description":4389,"children":-1},"Built-in authentication endpoints, token flows, and how to extend them",1793709777625]