[{"data":1,"prerenderedAt":613},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-agent-skill":177,"-getting-started-agent-skill-surround":608},[4,31,72,103,129,145,166],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":30},"Getting Started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":26,"path":27,"stem":28,"icon":29},"Agent Skill","\u002Fgetting-started\u002Fagent-skill","1.getting-started\u002F4.agent-skill","i-lucide-sparkles",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"Core","i-lucide-box","\u002Fcore","2.core",[37,42,47,52,57,62,67],{"title":38,"path":39,"stem":40,"icon":41},"Routing","\u002Fcore\u002Frouting","2.core\u002F1.routing","i-lucide-route",{"title":43,"path":44,"stem":45,"icon":46},"Handlers","\u002Fcore\u002Fhandlers","2.core\u002F2.handlers","i-lucide-braces",{"title":48,"path":49,"stem":50,"icon":51},"Request Binding","\u002Fcore\u002Frequest-binding","2.core\u002F3.request-binding","i-lucide-tags",{"title":53,"path":54,"stem":55,"icon":56},"Validation","\u002Fcore\u002Fvalidation","2.core\u002F4.validation","i-lucide-check-check",{"title":58,"path":59,"stem":60,"icon":61},"Context","\u002Fcore\u002Fcontext","2.core\u002F5.context","i-lucide-file-input",{"title":63,"path":64,"stem":65,"icon":66},"Errors","\u002Fcore\u002Ferrors","2.core\u002F6.errors","i-lucide-triangle-alert",{"title":68,"path":69,"stem":70,"icon":71},"Middleware","\u002Fcore\u002Fmiddleware","2.core\u002F7.middleware","i-lucide-layers",{"title":73,"icon":74,"path":75,"stem":76,"children":77,"page":30},"Auth","i-lucide-shield-check","\u002Fauth","3.auth",[78,83,88,93,98],{"title":79,"path":80,"stem":81,"icon":82},"Overview","\u002Fauth\u002Foverview","3.auth\u002F1.overview","i-lucide-shield",{"title":84,"path":85,"stem":86,"icon":87},"Auth Rules","\u002Fauth\u002Fauth-rules","3.auth\u002F2.auth-rules","i-lucide-lock",{"title":89,"path":90,"stem":91,"icon":92},"JWT Providers","\u002Fauth\u002Fjwt-providers","3.auth\u002F3.jwt-providers","i-lucide-key",{"title":94,"path":95,"stem":96,"icon":97},"Roles & Permissions","\u002Fauth\u002Froles-and-permissions","3.auth\u002F4.roles-and-permissions","i-lucide-users",{"title":99,"path":100,"stem":101,"icon":102},"Audit Logging","\u002Fauth\u002Faudit-logging","3.auth\u002F5.audit-logging","i-lucide-scroll-text",{"title":104,"icon":105,"path":106,"stem":107,"children":108,"page":30},"GoTrue","i-lucide-key-round","\u002Fgotrue","4.gotrue",[109,114,119,124],{"title":110,"path":111,"stem":112,"icon":113},"Proxy","\u002Fgotrue\u002Fproxy","4.gotrue\u002F1.proxy","i-lucide-shuffle",{"title":115,"path":116,"stem":117,"icon":118},"Endpoints","\u002Fgotrue\u002Fendpoints","4.gotrue\u002F2.endpoints","i-lucide-list",{"title":120,"path":121,"stem":122,"icon":123},"Client IP & Rate Limits","\u002Fgotrue\u002Fclient-ip-and-rate-limits","4.gotrue\u002F3.client-ip-and-rate-limits","i-lucide-network",{"title":125,"path":126,"stem":127,"icon":128},"Deployment","\u002Fgotrue\u002Fdeployment","4.gotrue\u002F4.deployment","i-lucide-server",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":30},"API Docs","i-lucide-file-text","\u002Fapi-docs","5.api-docs",[135,140],{"title":136,"path":137,"stem":138,"icon":139},"OpenAPI","\u002Fapi-docs\u002Fopenapi","5.api-docs\u002F1.openapi","i-lucide-file-json",{"title":141,"path":142,"stem":143,"icon":144},"Scalar UI","\u002Fapi-docs\u002Fscalar","5.api-docs\u002F2.scalar","i-lucide-book-open-text",{"title":146,"icon":147,"path":148,"stem":149,"children":150,"page":30},"Guides","i-lucide-compass","\u002Fguides","6.guides",[151,156,161],{"title":152,"path":153,"stem":154,"icon":155},"Testing","\u002Fguides\u002Ftesting","6.guides\u002F1.testing","i-lucide-flask-conical",{"title":157,"path":158,"stem":159,"icon":160},"Performance","\u002Fguides\u002Fperformance","6.guides\u002F2.performance","i-lucide-gauge",{"title":162,"path":163,"stem":164,"icon":165},"Releasing","\u002Fguides\u002Freleasing","6.guides\u002F3.releasing","i-lucide-tag",{"title":167,"icon":168,"path":169,"stem":170,"children":171,"page":30},"Reference","i-lucide-code","\u002Freference","7.reference",[172],{"title":173,"path":174,"stem":175,"icon":176},"API Reference","\u002Freference\u002Fapi-reference","7.reference\u002F1.api-reference","i-lucide-list-tree",{"id":178,"title":26,"body":179,"description":601,"extension":602,"links":603,"meta":604,"navigation":605,"path":27,"seo":606,"stem":28,"__hash__":607},"docs\u002F1.getting-started\u002F4.agent-skill.md",{"type":180,"value":181,"toc":593},"minimark",[182,194,199,229,235,250,254,261,409,413,416,511,517,521,524,528,547,573,577,589],[183,184,185,186,193],"p",{},"This site publishes an ",[187,188,192],"a",{"href":189,"rel":190},"https:\u002F\u002Fdocus.dev\u002Fen\u002Fai\u002Fskills",[191],"nofollow","agent skill",": a package of instructions that teaches a coding agent how ezz actually works. Point your agent's installer at this domain and it picks up the framework's shape, its conventions, and the handful of behaviours that are easy to get wrong.",[195,196,198],"h2",{"id":197},"install-it","Install it",[200,201,207],"pre",{"className":202,"code":203,"filename":204,"language":205,"meta":206,"style":206},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpx skills add https:\u002F\u002Fezz.sulv.org\n","Terminal","bash","",[208,209,210],"code",{"__ignoreMap":206},[211,212,215,219,223,226],"span",{"class":213,"line":214},"line",1,[211,216,218],{"class":217},"sBMFI","pnpx",[211,220,222],{"class":221},"sfazB"," skills",[211,224,225],{"class":221}," add",[211,227,228],{"class":221}," https:\u002F\u002Fezz.sulv.org\n",[183,230,231,234],{},[208,232,233],{},"npx skills add https:\u002F\u002Fezz.sulv.org"," does the same thing if you are not using pnpm.",[183,236,237,238,245,246,249],{},"The installer reads the discovery index at ",[187,239,242],{"href":240,"rel":241},"https:\u002F\u002Fezz.sulv.org\u002F.well-known\u002Fskills\u002Findex.json",[191],[208,243,244],{},"\u002F.well-known\u002Fskills\u002Findex.json",", which lists every skill this site publishes along with its files. There is one, named ",[208,247,248],{},"ezz",".",[195,251,253],{"id":252},"know-what-it-contains","Know what it contains",[183,255,256,257,260],{},"The skill leads with a short ",[208,258,259],{},"SKILL.md"," your agent always reads, and eleven reference files it loads only when the task calls for one. That split keeps the common case cheap: an agent writing a handler pulls in binding and validation, not the GoTrue proxy.",[262,263,264,277],"table",{},[265,266,267],"thead",{},[268,269,270,274],"tr",{},[271,272,273],"th",{},"File",[271,275,276],{},"Covers",[278,279,280,290,300,313,323,336,346,356,366,376,386,399],"tbody",{},[268,281,282,287],{},[283,284,285],"td",{},[208,286,259],{},[283,288,289],{},"Mental model, a complete runnable app, the traps, and a map to everything below",[268,291,292,297],{},[283,293,294],{},[208,295,296],{},"references\u002Frouting-and-groups.md",[283,298,299],{},"Patterns, groups, nesting, route metadata",[268,301,302,307],{},[283,303,304],{},[208,305,306],{},"references\u002Fhandlers-and-binding.md",[283,308,309,312],{},[208,310,311],{},"ezz.H",", the tag table, validation rules, response rules",[268,314,315,320],{},[283,316,317],{},[208,318,319],{},"references\u002Fcontext.md",[283,321,322],{},"Reading requests, writing responses, streaming, pooling",[268,324,325,330],{},[283,326,327],{},[208,328,329],{},"references\u002Ferrors.md",[283,331,332,335],{},[208,333,334],{},"HTTPError",", status mapping, panics",[268,337,338,343],{},[283,339,340],{},[208,341,342],{},"references\u002Fmiddleware.md",[283,344,345],{},"Defaults, ordering, CORS, gzip, rate limiting",[268,347,348,353],{},[283,349,350],{},[208,351,352],{},"references\u002Fauth.md",[283,354,355],{},"Providers, rules, precedence, custom credentials",[268,357,358,363],{},[283,359,360],{},[208,361,362],{},"references\u002Frbac.md",[283,364,365],{},"Resolvers, caching, hierarchies, audit logging",[268,367,368,373],{},[283,369,370],{},[208,371,372],{},"references\u002Fgotrue.md",[283,374,375],{},"Proxy setup, endpoints, client IP, deployment",[268,377,378,383],{},[283,379,380],{},[208,381,382],{},"references\u002Fopenapi.md",[283,384,385],{},"Generation, Scalar UI, what is and is not emitted",[268,387,388,393],{},[283,389,390],{},[208,391,392],{},"references\u002Ftesting.md",[283,394,395,398],{},[208,396,397],{},"TestApp",", handler tests, auth tests, proxy tests",[268,400,401,406],{},[283,402,403],{},[208,404,405],{},"references\u002Fapi-reference.md",[283,407,408],{},"The full exported surface, signature-dense",[195,410,412],{"id":411},"understand-what-it-corrects","Understand what it corrects",[183,414,415],{},"A model that has never seen ezz will fall back on habits from other Go frameworks, and several of those habits produce code that compiles and then misbehaves quietly. The skill front-loads exactly those cases:",[417,418,419,448,461,479,502],"ul",{},[420,421,422,429,430,433,434,437,438,441,442,445,446,249],"li",{},[423,424,425,428],"strong",{},[208,426,427],{},"validate"," supports six rules",", not the ",[208,431,432],{},"go-playground\u002Fvalidator"," set. ",[208,435,436],{},"uuid",", ",[208,439,440],{},"gte",", and ",[208,443,444],{},"oneof"," are ignored silently, so a field an agent believes is guarded is not. See ",[187,447,53],{"href":54},[420,449,450,453,454,457,458,249],{},[423,451,452],{},"A zero-value return writes no body."," A handler returning a nil pointer sends ",[208,455,456],{},"200"," with nothing in it. See ",[187,459,43],{"href":460},"\u002Fcore\u002Fhandlers#understand-when-the-response-is-written",[420,462,463,466,467,470,471,474,475,249],{},[423,464,465],{},"JSON bodies bind flat"," into the request struct, mixed with ",[208,468,469],{},"path"," and ",[208,472,473],{},"query"," fields, rather than into a nested body field. See ",[187,476,478],{"href":477},"\u002Fcore\u002Frequest-binding#understand-the-binding-order","Request binding",[420,480,481,490,491,494,495,498,499,249],{},[423,482,483,484,486,487,249],{},"Auth rules come from ",[208,485,248],{},", providers from ",[208,488,489],{},"auth"," ",[208,492,493],{},"auth.Role(...)"," is a leftover from an earlier design and does not satisfy ",[208,496,497],{},"ezz.AuthRule",". See ",[187,500,501],{"href":85},"Auth rules",[420,503,504,507,508,249],{},[423,505,506],{},"Middleware and group rules are snapshotted at registration",", so ordering matters. See ",[187,509,68],{"href":510},"\u002Fcore\u002Fmiddleware#understand-the-order",[183,512,513,514,516],{},"Every code sample in the skill is checked against the source in the repository, and the app in ",[208,515,259],{}," is compiled as part of keeping it honest.",[195,518,520],{"id":519},"keep-it-up-to-date","Keep it up to date",[183,522,523],{},"Re-run the install command to pull the current version. The skill is versioned with the docs site, so it describes the framework as of whatever is deployed here.",[195,525,527],{"id":526},"publish-it-from-your-own-build","Publish it from your own build",[183,529,530,531,534,535,538,539,542,543,546],{},"The skill lives in ",[208,532,533],{},"docs-site\u002Fskills\u002Fezz\u002F"," and is served by the Docus skills module, which scans a ",[208,536,537],{},"skills\u002F"," directory at the Nuxt root and needs no configuration. A local ",[208,540,541],{},"pnpm dev"," serves the same endpoints, so you can point an installer at ",[208,544,545],{},"http:\u002F\u002Flocalhost:3000"," to test a change before it ships.",[200,548,550],{"className":202,"code":549,"filename":204,"language":205,"meta":206,"style":206},"curl -s http:\u002F\u002Flocalhost:3000\u002F.well-known\u002Fskills\u002Findex.json\ncurl -s http:\u002F\u002Flocalhost:3000\u002F.well-known\u002Fskills\u002Fezz\u002FSKILL.md\n",[208,551,552,563],{"__ignoreMap":206},[211,553,554,557,560],{"class":213,"line":214},[211,555,556],{"class":217},"curl",[211,558,559],{"class":221}," -s",[211,561,562],{"class":221}," http:\u002F\u002Flocalhost:3000\u002F.well-known\u002Fskills\u002Findex.json\n",[211,564,566,568,570],{"class":213,"line":565},2,[211,567,556],{"class":217},[211,569,559],{"class":221},[211,571,572],{"class":221}," http:\u002F\u002Flocalhost:3000\u002F.well-known\u002Fskills\u002Fezz\u002FSKILL.md\n",[195,574,576],{"id":575},"where-to-go-next","Where to go next",[578,579,580,585],"card-group",{},[581,582,584],"card",{"icon":24,"title":583,"to":22},"Quick start","Build the API yourself, with or without an agent.",[581,586,588],{"icon":176,"title":587,"to":174},"API reference","The same surface the skill's reference file distils.",[590,591,592],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":206,"searchDepth":565,"depth":565,"links":594},[595,596,597,598,599,600],{"id":197,"depth":565,"text":198},{"id":252,"depth":565,"text":253},{"id":411,"depth":565,"text":412},{"id":519,"depth":565,"text":520},{"id":526,"depth":565,"text":527},{"id":575,"depth":565,"text":576},"Install the ezz agent skill so Claude Code, Cursor, and other coding agents write ezz correctly the first time.","md",null,{},{"icon":29},{"title":26,"description":601},"OaX5jukLNLXlRZunNhj62itQ9bWB_4FRMKcUhh3ggEY",[609,611],{"title":21,"path":22,"stem":23,"description":610,"icon":24,"children":-1},"Build an authenticated JSON API with generated OpenAPI docs in one file.",{"title":38,"path":39,"stem":40,"description":612,"icon":41,"children":-1},"Register routes, use path patterns, group them, and attach metadata.",1789474274747]