[{"data":1,"prerenderedAt":4321},["ShallowReactive",2],{"navigation_docs_hu":3,"-hu-framework-server":449,"-hu-framework-server-surround":4316},[4,45,120,158,174,204,234,260,272,288,308,327,340,357,374,387,399,426],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Kezdő lépések","i-lucide-rocket","\u002Fhu\u002Fgetting-started","hu\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"Bevezetés","\u002Fhu\u002Fgetting-started\u002Fintroduction","hu\u002F01.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Telepítés","\u002Fhu\u002Fgetting-started\u002Finstallation","hu\u002F01.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Az első modulod","\u002Fhu\u002Fgetting-started\u002Ffirst-module","hu\u002F01.getting-started\u002F3.first-module","i-lucide-package-plus",{"title":26,"path":27,"stem":28,"icon":29},"Projektstruktúra","\u002Fhu\u002Fgetting-started\u002Fproject-structure","hu\u002F01.getting-started\u002F4.project-structure","i-lucide-folder-tree",{"title":31,"path":32,"stem":33,"icon":34},"A shop mintaalkalmazás","\u002Fhu\u002Fgetting-started\u002Fsample-app","hu\u002F01.getting-started\u002F5.sample-app","i-lucide-shopping-cart",{"title":36,"path":37,"stem":38,"icon":39},"Laravelből érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-laravel","hu\u002F01.getting-started\u002F6.coming-from-laravel","i-lucide-arrow-right-left",{"title":41,"path":42,"stem":43,"icon":39},"Symfonyból érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-symfony","hu\u002F01.getting-started\u002F7.coming-from-symfony",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"CLI referencia","i-lucide-terminal","\u002Fhu\u002Fcli","hu\u002F02.cli",[51,55,60,65,70,75,80,85,90,95,100,105,110,115],{"title":52,"path":53,"stem":54,"icon":47},"Áttekintés","\u002Fhu\u002Fcli\u002Foverview","hu\u002F02.cli\u002F1.overview",{"title":56,"path":57,"stem":58,"icon":59},"add compose \u002F add docker","\u002Fhu\u002Fcli\u002Fadd-compose","hu\u002F02.cli\u002F10.add-compose","i-lucide-container",{"title":61,"path":62,"stem":63,"icon":64},"add mail","\u002Fhu\u002Fcli\u002Fadd-mail","hu\u002F02.cli\u002F11.add-mail","i-lucide-mail-plus",{"title":66,"path":67,"stem":68,"icon":69},"add notification","\u002Fhu\u002Fcli\u002Fadd-notification","hu\u002F02.cli\u002F12.add-notification","i-lucide-bell-plus",{"title":71,"path":72,"stem":73,"icon":74},"add realtime","\u002Fhu\u002Fcli\u002Fadd-realtime","hu\u002F02.cli\u002F13.add-realtime","i-lucide-radio-tower",{"title":76,"path":77,"stem":78,"icon":79},"add seeder","\u002Fhu\u002Fcli\u002Fadd-seeder","hu\u002F02.cli\u002F14.add-seeder","i-lucide-sprout",{"title":81,"path":82,"stem":83,"icon":84},"new project","\u002Fhu\u002Fcli\u002Fnew-project","hu\u002F02.cli\u002F2.new-project","i-lucide-folder-plus",{"title":86,"path":87,"stem":88,"icon":89},"new module","\u002Fhu\u002Fcli\u002Fnew-module","hu\u002F02.cli\u002F3.new-module","i-lucide-blocks",{"title":91,"path":92,"stem":93,"icon":94},"add surface","\u002Fhu\u002Fcli\u002Fadd-surface","hu\u002F02.cli\u002F4.add-surface","i-lucide-layers-2",{"title":96,"path":97,"stem":98,"icon":99},"add domain","\u002Fhu\u002Fcli\u002Fadd-domain","hu\u002F02.cli\u002F5.add-domain","i-lucide-box",{"title":101,"path":102,"stem":103,"icon":104},"add handler","\u002Fhu\u002Fcli\u002Fadd-handler","hu\u002F02.cli\u002F6.add-handler","i-lucide-webhook",{"title":106,"path":107,"stem":108,"icon":109},"new migration","\u002Fhu\u002Fcli\u002Fnew-migration","hu\u002F02.cli\u002F7.new-migration","i-lucide-file-plus",{"title":111,"path":112,"stem":113,"icon":114},"worker generátorok","\u002Fhu\u002Fcli\u002Fworker-generators","hu\u002F02.cli\u002F8.worker-generators","i-lucide-cog",{"title":116,"path":117,"stem":118,"icon":119},"add db","\u002Fhu\u002Fcli\u002Fadd-db","hu\u002F02.cli\u002F9.add-db","i-lucide-database-zap",{"title":121,"icon":99,"path":122,"stem":123,"children":124,"page":44},"A framework","\u002Fhu\u002Fframework","hu\u002F03.framework",[125,129,134,139,143,148,153],{"title":126,"path":127,"stem":128,"icon":99},"A framework áttekintése","\u002Fhu\u002Fframework\u002Foverview","hu\u002F03.framework\u002F1.overview",{"title":130,"path":131,"stem":132,"icon":133},"Alkalmazás-életciklus","\u002Fhu\u002Fframework\u002Fapp","hu\u002F03.framework\u002F2.app","i-lucide-power",{"title":135,"path":136,"stem":137,"icon":138},"Szerver","\u002Fhu\u002Fframework\u002Fserver","hu\u002F03.framework\u002F3.server","i-lucide-server",{"title":140,"path":141,"stem":142,"icon":114},"Worker","\u002Fhu\u002Fframework\u002Fworker","hu\u002F03.framework\u002F4.worker",{"title":144,"path":145,"stem":146,"icon":147},"Realtime","\u002Fhu\u002Fframework\u002Frealtime","hu\u002F03.framework\u002F5.realtime","i-lucide-radio",{"title":149,"path":150,"stem":151,"icon":152},"Migrációk","\u002Fhu\u002Fframework\u002Fmigrations","hu\u002F03.framework\u002F6.migrations","i-lucide-file-stack",{"title":154,"path":155,"stem":156,"icon":157},"Social login","\u002Fhu\u002Fframework\u002Fsocial-login","hu\u002F03.framework\u002F7.social-login","i-lucide-log-in",{"title":159,"icon":160,"path":161,"stem":162,"children":163,"page":44},"Referencia","i-lucide-book-open","\u002Fhu\u002Freference","hu\u002F04.reference",[164,169],{"title":165,"path":166,"stem":167,"icon":168},"Konfiguráció","\u002Fhu\u002Freference\u002Fconfiguration","hu\u002F04.reference\u002F1.configuration","i-lucide-settings",{"title":170,"path":171,"stem":172,"icon":173},"Külső függőségek","\u002Fhu\u002Freference\u002Fdependencies","hu\u002F04.reference\u002F2.dependencies","i-lucide-package",{"title":175,"icon":176,"path":177,"stem":178,"children":179,"page":44},"Koncepciók","i-lucide-lightbulb","\u002Fhu\u002Fconcepts","hu\u002F05.concepts",[180,185,190,194,199],{"title":181,"path":182,"stem":183,"icon":184},"Architektúra","\u002Fhu\u002Fconcepts\u002Farchitecture","hu\u002F05.concepts\u002F1.architecture","i-lucide-layers",{"title":186,"path":187,"stem":188,"icon":189},"Hibamodell","\u002Fhu\u002Fconcepts\u002Ferror-model","hu\u002F05.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":165,"path":191,"stem":192,"icon":193},"\u002Fhu\u002Fconcepts\u002Fconfiguration","hu\u002F05.concepts\u002F3.configuration","i-lucide-settings-2",{"title":195,"path":196,"stem":197,"icon":198},"Codegen pipeline","\u002Fhu\u002Fconcepts\u002Fcodegen-pipeline","hu\u002F05.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":200,"path":201,"stem":202,"icon":203},"Design patternek","\u002Fhu\u002Fconcepts\u002Fdesign-patterns","hu\u002F05.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":205,"icon":206,"path":207,"stem":208,"children":209,"page":44},"auth","i-lucide-shield-check","\u002Fhu\u002Fauth","hu\u002F06.auth",[210,215,220,225,230],{"title":211,"path":212,"stem":213,"icon":214},"Autentikáció","\u002Fhu\u002Fauth\u002Foverview","hu\u002F06.auth\u002F1.overview","i-lucide-key-round",{"title":216,"path":217,"stem":218,"icon":219},"RBAC","\u002Fhu\u002Fauth\u002Frbac","hu\u002F06.auth\u002F2.rbac","i-lucide-users",{"title":221,"path":222,"stem":223,"icon":224},"Policy-k","\u002Fhu\u002Fauth\u002Fpolicy","hu\u002F06.auth\u002F3.policy","i-lucide-gavel",{"title":226,"path":227,"stem":228,"icon":229},"Az auth önálló használata","\u002Fhu\u002Fauth\u002Fstandalone","hu\u002F06.auth\u002F4.standalone","i-lucide-plug",{"title":231,"path":232,"stem":233,"icon":157},"Social login goth-tal, önállóan","\u002Fhu\u002Fauth\u002Fsocial-standalone","hu\u002F06.auth\u002F5.social-standalone",{"title":235,"icon":236,"path":237,"stem":238,"children":239,"page":44},"dbx","i-lucide-database","\u002Fhu\u002Fdbx","hu\u002F07.dbx",[240,243,247,251,256],{"title":52,"path":241,"stem":242,"icon":236},"\u002Fhu\u002Fdbx\u002Foverview","hu\u002F07.dbx\u002F1.overview",{"title":244,"path":245,"stem":246,"icon":229},"pgx","\u002Fhu\u002Fdbx\u002Fpg","hu\u002F07.dbx\u002F2.pg",{"title":248,"path":249,"stem":250,"icon":184},"bun","\u002Fhu\u002Fdbx\u002Fbunx","hu\u002F07.dbx\u002F3.bunx",{"title":252,"path":253,"stem":254,"icon":255},"Tranzakciók","\u002Fhu\u002Fdbx\u002Ftransactions","hu\u002F07.dbx\u002F4.transactions","i-lucide-git-merge",{"title":257,"path":258,"stem":259,"icon":79},"Seederek","\u002Fhu\u002Fdbx\u002Fseed","hu\u002F07.dbx\u002F5.seed",{"title":261,"icon":193,"path":262,"stem":263,"children":264,"page":44},"envconf","\u002Fhu\u002Fenvconf","hu\u002F08.envconf",[265,268],{"title":52,"path":266,"stem":267,"icon":193},"\u002Fhu\u002Fenvconf\u002Foverview","hu\u002F08.envconf\u002F1.overview",{"title":269,"path":270,"stem":271,"icon":193},"Receptek","\u002Fhu\u002Fenvconf\u002Frecipes","hu\u002F08.envconf\u002F2.recipes",{"title":273,"icon":189,"path":274,"stem":275,"children":276,"page":44},"errs","\u002Fhu\u002Ferrs","hu\u002F09.errs",[277,280,284],{"title":52,"path":278,"stem":279,"icon":189},"\u002Fhu\u002Ferrs\u002Foverview","hu\u002F09.errs\u002F1.overview",{"title":281,"path":282,"stem":283,"icon":189},"API","\u002Fhu\u002Ferrs\u002Fapi","hu\u002F09.errs\u002F2.api",{"title":285,"path":286,"stem":287,"icon":189},"Integráció","\u002Fhu\u002Ferrs\u002Fintegration","hu\u002F09.errs\u002F3.integration",{"title":289,"icon":290,"path":291,"stem":292,"children":293,"page":44},"events","i-lucide-workflow","\u002Fhu\u002Fevents","hu\u002F10.events",[294,298,303],{"title":295,"path":296,"stem":297,"icon":147},"Események","\u002Fhu\u002Fevents\u002Foverview","hu\u002F10.events\u002F1.overview",{"title":299,"path":300,"stem":301,"icon":302},"Outbox","\u002Fhu\u002Fevents\u002Foutbox","hu\u002F10.events\u002F2.outbox","i-lucide-inbox",{"title":304,"path":305,"stem":306,"icon":307},"Ütemezés","\u002Fhu\u002Fevents\u002Fscheduler","hu\u002F10.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":309,"icon":310,"path":311,"stem":312,"children":313,"page":44},"httperr","i-lucide-globe","\u002Fhu\u002Fhttperr","hu\u002F11.httperr",[314,317,322],{"title":52,"path":315,"stem":316,"icon":310},"\u002Fhu\u002Fhttperr\u002Foverview","hu\u002F11.httperr\u002F1.overview",{"title":318,"path":319,"stem":320,"icon":321},"Hibaválaszok","\u002Fhu\u002Fhttperr\u002Ferror-responses","hu\u002F11.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":323,"path":324,"stem":325,"icon":326},"Validáció","\u002Fhu\u002Fhttperr\u002Fvalidation","hu\u002F11.httperr\u002F3.validation","i-lucide-badge-check",{"title":328,"icon":329,"path":330,"stem":331,"children":332,"page":44},"logx","i-lucide-scroll-text","\u002Fhu\u002Flogx","hu\u002F12.logx",[333,336],{"title":52,"path":334,"stem":335,"icon":329},"\u002Fhu\u002Flogx\u002Foverview","hu\u002F12.logx\u002F1.overview",{"title":337,"path":338,"stem":339,"icon":47},"Monolog-formázó","\u002Fhu\u002Flogx\u002Fmonolog","hu\u002F12.logx\u002F2.monolog",{"title":341,"icon":342,"path":343,"stem":344,"children":345,"page":44},"mail","i-lucide-mail","\u002Fhu\u002Fmail","hu\u002F13.mail",[346,349,353],{"title":52,"path":347,"stem":348,"icon":342},"\u002Fhu\u002Fmail\u002Foverview","hu\u002F13.mail\u002F1.overview",{"title":350,"path":351,"stem":352,"icon":342},"SMTP","\u002Fhu\u002Fmail\u002Fsmtp","hu\u002F13.mail\u002F2.smtp",{"title":354,"path":355,"stem":356,"icon":342},"MJML","\u002Fhu\u002Fmail\u002Fmjml","hu\u002F13.mail\u002F3.mjml",{"title":358,"icon":359,"path":360,"stem":361,"children":362,"page":44},"notify","i-lucide-bell","\u002Fhu\u002Fnotify","hu\u002F14.notify",[363,366,370],{"title":52,"path":364,"stem":365,"icon":359},"\u002Fhu\u002Fnotify\u002Foverview","hu\u002F14.notify\u002F1.overview",{"title":367,"path":368,"stem":369,"icon":359},"Database csatorna","\u002Fhu\u002Fnotify\u002Fdatabase","hu\u002F14.notify\u002F2.database",{"title":371,"path":372,"stem":373,"icon":359},"Broadcast csatorna","\u002Fhu\u002Fnotify\u002Fbroadcast","hu\u002F14.notify\u002F3.broadcast",{"title":375,"icon":376,"path":377,"stem":378,"children":379,"page":44},"paginate","i-lucide-list-ordered","\u002Fhu\u002Fpaginate","hu\u002F15.paginate",[380,383],{"title":52,"path":381,"stem":382,"icon":376},"\u002Fhu\u002Fpaginate\u002Foverview","hu\u002F15.paginate\u002F1.overview",{"title":384,"path":385,"stem":386,"icon":39},"Cursor-lapozás","\u002Fhu\u002Fpaginate\u002Fcursor","hu\u002F15.paginate\u002F2.cursor",{"title":388,"icon":184,"path":389,"stem":390,"children":391,"page":44},"queue","\u002Fhu\u002Fqueue","hu\u002F16.queue",[392,395],{"title":52,"path":393,"stem":394,"icon":376},"\u002Fhu\u002Fqueue\u002Foverview","hu\u002F16.queue\u002F1.overview",{"title":396,"path":397,"stem":398,"icon":184},"Taskok","\u002Fhu\u002Fqueue\u002Ftasks","hu\u002F16.queue\u002F2.tasks",{"title":400,"icon":401,"path":402,"stem":403,"children":404,"page":44},"storage","i-lucide-hard-drive","\u002Fhu\u002Fstorage","hu\u002F17.storage",[405,408,412,416,421],{"title":52,"path":406,"stem":407,"icon":401},"\u002Fhu\u002Fstorage\u002Foverview","hu\u002F17.storage\u002F1.overview",{"title":409,"path":410,"stem":411,"icon":401},"Disk API","\u002Fhu\u002Fstorage\u002Fdisk-api","hu\u002F17.storage\u002F2.disk-api",{"title":413,"path":414,"stem":415,"icon":401},"Memória és helyi lemez","\u002Fhu\u002Fstorage\u002Flocal","hu\u002F17.storage\u002F3.local",{"title":417,"path":418,"stem":419,"icon":420},"S3","\u002Fhu\u002Fstorage\u002Fs3","hu\u002F17.storage\u002F4.s3","i-lucide-cloud",{"title":422,"path":423,"stem":424,"icon":425},"Tesztelés","\u002Fhu\u002Fstorage\u002Ftesting","hu\u002F17.storage\u002F5.testing","i-lucide-flask-conical",{"title":427,"icon":428,"path":429,"stem":430,"children":431,"page":44},"telemetry","i-lucide-activity","\u002Fhu\u002Ftelemetry","hu\u002F18.telemetry",[432,435,439,444],{"title":52,"path":433,"stem":434,"icon":428},"\u002Fhu\u002Ftelemetry\u002Foverview","hu\u002F18.telemetry\u002F1.overview",{"title":436,"path":437,"stem":438,"icon":329},"Logolás","\u002Fhu\u002Ftelemetry\u002Flogging","hu\u002F18.telemetry\u002F2.logging",{"title":440,"path":441,"stem":442,"icon":443},"OpenTelemetry","\u002Fhu\u002Ftelemetry\u002Fopentelemetry","hu\u002F18.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":445,"path":446,"stem":447,"icon":448},"Sentry","\u002Fhu\u002Ftelemetry\u002Fsentry","hu\u002F18.telemetry\u002F4.sentry","i-lucide-bug",{"id":450,"title":135,"body":451,"description":4309,"extension":4310,"links":4311,"meta":4312,"navigation":4313,"path":136,"seo":4314,"stem":137,"__hash__":4315},"docs_hu\u002Fhu\u002F03.framework\u002F3.server.md",{"type":452,"value":453,"toc":4287},"minimark",[454,499,528,546,551,564,634,637,1009,1015,1020,1023,1052,1056,1119,1144,1147,1181,1185,1226,1230,1253,1298,1307,1313,1317,1440,1481,1495,1773,1806,1838,1851,1867,1871,1874,1919,1923,1929,2583,2614,2618,2875,2973,2977,2996,3348,3351,3436,3440,3558,3573,3598,3602,3617,3958,4004,4045,4048,4057,4211,4214,4218,4250,4254,4283],[455,456,457,458,462,463,470,471,474,475,478,479,483,484,486,487,490,491,494,495,498],"p",{},"A ",[459,460,461],"code",{},"server"," a framework HTTP-chassis-a: egy ",[464,465,469],"a",{"href":466,"rel":467},"https:\u002F\u002Fgithub.com\u002Fgo-chi\u002Fchi",[468],"nofollow","chi"," router a standard ",[459,472,473],{},"net\u002Fhttp"," fölött, a framework hibakezelésével, validációjával és telemetriájával bekötve, a ",[464,476,477],{"href":131},"közös életciklus"," alatt futtatva. A pozicionálása ",[480,481,482],"strong",{},"stdlib-first",": a chi nem framework, hanem routing a ",[459,485,473],{}," fölött. Minden middleware sima ",[459,488,489],{},"func(http.Handler) http.Handler",", minden handler ",[459,492,493],{},"http.HandlerFunc","-kompatibilis, így a Go-ökoszisztéma bármely net\u002Fhttp-eszköze (middleware-libek, ",[459,496,497],{},"httptest",", profilerek) módosítás nélkül működik.",[500,501,506],"pre",{"className":502,"code":503,"language":504,"meta":505,"style":505},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import \"github.com\u002Fgp-system\u002Fframework\u002Fserver\"\n","go","",[459,507,508],{"__ignoreMap":505},[509,510,513,517,521,525],"span",{"class":511,"line":512},"line",1,[509,514,516],{"class":515},"s7zQu","import",[509,518,520],{"class":519},"sMK4o"," \"",[509,522,524],{"class":523},"sBMFI","github.com\u002Fgp-system\u002Fframework\u002Fserver",[509,526,527],{"class":519},"\"\n",[455,529,530,531,534,535,537,538,541,542,545],{},"Ez a chassis-a minden ",[464,532,533],{"href":82},"generált"," projektnek; az alkalmazáskód sosem beszél közvetlenül a ",[459,536,473],{},"-vel, egyszer, a ",[459,539,540],{},"main","-ben hívja meg a ",[459,543,544],{},"server.Run","-t.",[547,548,550],"h2",{"id":549},"config","Config",[455,552,553,554,557,558,563],{},"A generált projektben a ",[459,555,556],{},"server.Config"," prefix nélkül ágyazódik az alkalmazás konfigjába, és az ",[464,559,560],{"href":266},[459,561,562],{},"envconf.MustLoad"," tölti env-változókból:",[500,565,568],{"className":502,"code":566,"filename":567,"language":504,"meta":505,"style":505},"type Config struct {\n    Server server.Config\n    DB     dbx.Config `envPrefix:\"DB_\"`\n    \u002F\u002F ...\n}\n","internal\u002Fplatform\u002Fconfig\u002Fconfig.go",[459,569,570,584,599,621,628],{"__ignoreMap":505},[509,571,572,575,578,581],{"class":511,"line":512},[509,573,574],{"class":519},"type",[509,576,577],{"class":523}," Config",[509,579,580],{"class":519}," struct",[509,582,583],{"class":519}," {\n",[509,585,587,591,593,596],{"class":511,"line":586},2,[509,588,590],{"class":589},"sTEyZ","    Server ",[509,592,461],{"class":523},[509,594,595],{"class":519},".",[509,597,598],{"class":523},"Config\n",[509,600,602,605,607,609,611,614,618],{"class":511,"line":601},3,[509,603,604],{"class":589},"    DB     ",[509,606,235],{"class":523},[509,608,595],{"class":519},[509,610,550],{"class":523},[509,612,613],{"class":519}," `",[509,615,617],{"class":616},"sfazB","envPrefix:\"DB_\"",[509,619,620],{"class":519},"`\n",[509,622,624],{"class":511,"line":623},4,[509,625,627],{"class":626},"sHwdD","    \u002F\u002F ...\n",[509,629,631],{"class":511,"line":630},5,[509,632,633],{"class":519},"}\n",[455,635,636],{},"A mezők és env-változóik:",[638,639,640,659],"table",{},[641,642,643],"thead",{},[644,645,646,650,653,656],"tr",{},[647,648,649],"th",{},"Mező",[647,651,652],{},"Env",[647,654,655],{},"Default",[647,657,658],{},"Mit szabályoz",[660,661,662,683,711,731,751,772,792,812,832,852,872,906,925,947,968,987],"tbody",{},[644,663,664,670,675,680],{},[665,666,667],"td",{},[459,668,669],{},"ListenAddr",[665,671,672],{},[459,673,674],{},"LISTEN_ADDR",[665,676,677],{},[459,678,679],{},":3000",[665,681,682],{},"a cím, amin a szerver hallgat",[644,684,685,690,695,700],{},[665,686,687],{},[459,688,689],{},"ShutdownTimeout",[665,691,692],{},[459,693,694],{},"SHUTDOWN_TIMEOUT",[665,696,697],{},[459,698,699],{},"10s",[665,701,702,703,706,707,710],{},"mennyi ideje van az in-flight kéréseknek ",[459,704,705],{},"SIGINT","\u002F",[459,708,709],{},"SIGTERM"," után",[644,712,713,718,723,728],{},[665,714,715],{},[459,716,717],{},"ReadHeaderTimeout",[665,719,720],{},[459,721,722],{},"READ_HEADER_TIMEOUT",[665,724,725],{},[459,726,727],{},"5s",[665,729,730],{},"meddig küldheti a kliens a kérés fejléceit (Slowloris-védelem)",[644,732,733,738,743,748],{},[665,734,735],{},[459,736,737],{},"ReadTimeout",[665,739,740],{},[459,741,742],{},"READ_TIMEOUT",[665,744,745],{},[459,746,747],{},"30s",[665,749,750],{},"a teljes kérés (fejléc + body) beolvasásának kerete",[644,752,753,758,763,769],{},[665,754,755],{},[459,756,757],{},"WriteTimeout",[665,759,760],{},[459,761,762],{},"WRITE_TIMEOUT",[665,764,765,768],{},[459,766,767],{},"0s"," (kikapcsolva)",[665,770,771],{},"a válasz kiírásának kerete",[644,773,774,779,784,789],{},[665,775,776],{},[459,777,778],{},"IdleTimeout",[665,780,781],{},[459,782,783],{},"IDLE_TIMEOUT",[665,785,786],{},[459,787,788],{},"120s",[665,790,791],{},"meddig marad nyitva egy tétlen keep-alive kapcsolat",[644,793,794,799,804,809],{},[665,795,796],{},[459,797,798],{},"CORSOrigins",[665,800,801],{},[459,802,803],{},"CORS_ORIGINS",[665,805,806],{},[459,807,808],{},"*",[665,810,811],{},"engedélyezett originok, vesszővel elválasztva",[644,813,814,819,824,829],{},[665,815,816],{},[459,817,818],{},"CORSMethods",[665,820,821],{},[459,822,823],{},"CORS_METHODS",[665,825,826],{},[459,827,828],{},"GET,POST,PUT,PATCH,DELETE,OPTIONS",[665,830,831],{},"a CORS-preflightok által engedett metódusok",[644,833,834,839,844,849],{},[665,835,836],{},[459,837,838],{},"CORSHeaders",[665,840,841],{},[459,842,843],{},"CORS_HEADERS",[665,845,846],{},[459,847,848],{},"Content-Type,Authorization",[665,850,851],{},"a CORS-preflightok által engedett kérés-fejlécek",[644,853,854,859,864,869],{},[665,855,856],{},[459,857,858],{},"CORSAllowCredentials",[665,860,861],{},[459,862,863],{},"CORS_ALLOW_CREDENTIALS",[665,865,866],{},[459,867,868],{},"false",[665,870,871],{},"cookie-k\u002Fcredentialök cross-origin kéréseken (wildcard originokkal együtt érvénytelen)",[644,873,874,879,884,888],{},[665,875,876],{},[459,877,878],{},"TrustProxy",[665,880,881],{},[459,882,883],{},"HTTP_TRUST_PROXY",[665,885,886],{},[459,887,868],{},[665,889,890,891,894,895,898,899,706,902,905],{},"a ",[459,892,893],{},"realip"," middleware: a ",[459,896,897],{},"RemoteAddr"," az ",[459,900,901],{},"X-Real-Ip",[459,903,904],{},"X-Forwarded-For","-ból íródik át; csak olyan proxy mögött kapcsold be, ami felülírja ezeket a fejléceket",[644,907,908,913,918,922],{},[665,909,910],{},[459,911,912],{},"AccessLog",[665,914,915],{},[459,916,917],{},"HTTP_ACCESS_LOG",[665,919,920],{},[459,921,868],{},[665,923,924],{},"a strukturált access log (kérésenként egy rekord); telemetria dev módban ettől függetlenül mindig logol",[644,926,927,932,937,941],{},[665,928,929],{},[459,930,931],{},"RequestTimeout",[665,933,934],{},[459,935,936],{},"HTTP_REQUEST_TIMEOUT",[665,938,939,768],{},[459,940,767],{},[665,942,890,943,946],{},[459,944,945],{},"timeout"," middleware: kérésenkénti context-határidő; alapból ki, mert a streamelő válaszokat is elvágná",[644,948,949,954,959,965],{},[665,950,951],{},[459,952,953],{},"BodyLimit",[665,955,956],{},[459,957,958],{},"BODY_LIMIT",[665,960,961,964],{},[459,962,963],{},"4194304"," (4 MiB)",[665,966,967],{},"max kérés-body méret bájtban",[644,969,970,975,980,984],{},[665,971,972],{},[459,973,974],{},"ExposeInternalErrors",[665,976,977],{},[459,978,979],{},"HTTP_EXPOSE_INTERNAL_ERRORS",[665,981,982],{},[459,983,868],{},[665,985,986],{},"belső hibarészletek az 5xx válaszokban (csak dev!)",[644,988,989,994,1000,1003],{},[665,990,991],{},[459,992,993],{},"Telemetry",[665,995,996],{},[997,998,999],"em",{},"(beágyazott)",[665,1001,1002],{},"nincs",[665,1004,1005,1008],{},[459,1006,1007],{},"telemetry.Config"," (OTel, logger, Sentry)",[455,1010,1011,1012,595],{},"A teljes env-referencia (a DB-, worker- és telemetria-változókkal együtt): ",[464,1013,1014],{"href":166},"Konfiguráció-referencia",[1016,1017,1019],"h3",{"id":1018},"timeoutok","Timeoutok",[455,1021,1022],{},"A defaultok éles forgalomra vannak hangolva, nem demókra:",[1024,1025,1026,1034,1041],"ul",{},[1027,1028,1029,1033],"li",{},[480,1030,1031],{},[459,1032,717],{}," a Slowloris-védelem első vonala: egy kliens, aki bájtonként csöpögteti a fejléceket, 5 másodperc után lekapcsolódik.",[1027,1035,1036,1040],{},[480,1037,1038],{},[459,1039,737],{}," a teljes kérés beolvasását fedi.",[1027,1042,1043,1047,1048,1051],{},[480,1044,1045],{},[459,1046,757],{}," szándékosan ",[459,1049,1050],{},"0"," (kikapcsolva): a lassú vagy streamelő válaszokat (nagy letöltés, SSE) is elvágná. Kapcsold be, ha minden endpointod rövid életű.",[1016,1053,1055],{"id":1054},"body-limit-sosem-kapcsolható-ki-véletlenül","Body limit: sosem kapcsolható ki véletlenül",[500,1057,1059],{"className":502,"code":1058,"language":504,"meta":505,"style":505},"const DefaultBodyLimit = 4 \u003C\u003C 20 \u002F\u002F 4 MiB\n\nfunc (c Config) EffectiveBodyLimit() int\n",[459,1060,1061,1085,1091],{"__ignoreMap":505},[509,1062,1063,1066,1069,1072,1076,1079,1082],{"class":511,"line":512},[509,1064,1065],{"class":519},"const",[509,1067,1068],{"class":589}," DefaultBodyLimit ",[509,1070,1071],{"class":519},"=",[509,1073,1075],{"class":1074},"sbssI"," 4",[509,1077,1078],{"class":519}," \u003C\u003C",[509,1080,1081],{"class":1074}," 20",[509,1083,1084],{"class":626}," \u002F\u002F 4 MiB\n",[509,1086,1087],{"class":511,"line":586},[509,1088,1090],{"emptyLinePlaceholder":1089},true,"\n",[509,1092,1093,1096,1099,1103,1105,1108,1112,1115],{"class":511,"line":601},[509,1094,1095],{"class":519},"func",[509,1097,1098],{"class":519}," (",[509,1100,1102],{"class":1101},"sHdIc","c ",[509,1104,550],{"class":523},[509,1106,1107],{"class":519},")",[509,1109,1111],{"class":1110},"s2Zo4"," EffectiveBodyLimit",[509,1113,1114],{"class":519},"()",[509,1116,1118],{"class":1117},"spNyl"," int\n",[455,1120,457,1121,1123,1124,1126,1127,1130,1131,1133,1134,1137,1138,1140,1141,595],{},[459,1122,461],{}," sosem a nyers ",[459,1125,953],{}," mezőt olvassa, hanem az ",[459,1128,1129],{},"EffectiveBodyLimit()","-et: egy ",[459,1132,1050],{}," vagy negatív érték ",[480,1135,1136],{},"nem"," „korlátlant\" jelent, hanem visszaesik a 4 MiB defaultra. Egy elgépelt vagy üresen hagyott ",[459,1139,958],{}," így nem tudja észrevétlenül levenni a sapkát. A limit túllépése 413-as ",[464,1142,1143],{"href":319},"problem-válasz",[1016,1145,979],{"id":1146},"http_expose_internal_errors",[455,1148,1149,1152,1153,1156,1157,1161,1162,1165,1166,1169,1170,1173,1174,1177,1178,1180],{},[459,1150,1151],{},"true"," értékkel az 5xx válaszok ",[459,1154,1155],{},"detail","-je a mögöttes hibaüzenetet hordozza, és, ha a láncban ",[464,1158,1159],{"href":278},[459,1160,273],{}," hiba van, a válasz ",[459,1163,1164],{},"stack"," és ",[459,1167,1168],{},"chain"," extension membereket is kap. Szándékosan ",[480,1171,1172],{},"külön"," kapcsoló az ",[459,1175,1176],{},"OTEL_DEV_MODE","-tól: a dev-logolás bekapcsolása így nem kezdhet el véletlenül belső részleteket szivárogtatni a klienseknek. Productionben hagyd ",[459,1179,868],{},"-on: a részletek ott a logba és a Sentry-be mennek, nem a válaszba.",[1016,1182,1184],{"id":1183},"a-beágyazott-telemetria","A beágyazott telemetria",[455,1186,457,1187,1189,1190,1192,1193,1196,1197,1200,1201,1200,1203,1200,1206,1209,1210,1212,1213,1216,1217,1222,1223,595],{},[459,1188,993],{}," mező egy ",[459,1191,1007],{},": az OTel bootstrap, az alapértelmezett ",[459,1194,1195],{},"slog"," logger és az opcionális Sentry-integráció beállításai (",[459,1198,1199],{},"OTEL_SERVICE_NAME",", ",[459,1202,1176],{},[459,1204,1205],{},"LOG_LEVEL",[459,1207,1208],{},"SENTRY_DSN",", ..., mind standard név, prefix nélkül). A ",[459,1211,544],{}," ezt, a ",[459,1214,1215],{},"cfg.Log","-gal együtt, átadja az ",[464,1218,1219],{"href":131},[459,1220,1221],{},"app.Telemetry","-nak, mielőtt bármi más elindulna. Részletek: ",[464,1224,1225],{"href":433},"Observability",[547,1227,1229],{"id":1228},"a-közös-életciklus","A közös életciklus",[455,1231,457,1232,1234,1235,1240,1241,1246,1247,1252],{},[459,1233,461],{}," nem maga implementálja a graceful shutdownt: az engine-agnosztikus ",[464,1236,1237],{"href":131},[459,1238,1239],{},"app"," csomagra delegál, ugyanarra, amire a ",[464,1242,1243],{"href":141},[459,1244,1245],{},"worker"," és a ",[464,1248,1249],{"href":145},[459,1250,1251],{},"realtime"," is épül. A folyamat minden gpsystem-processzben ugyanaz:",[1254,1255,1256,1261,1268,1271,1285,1295],"ol",{},[1027,1257,1258,1260],{},[459,1259,1221],{},": OTel, logger, Sentry.",[1027,1262,1263,1264,1267],{},"Route-regisztráció (a te ",[459,1265,1266],{},"register"," függvényed).",[1027,1269,1270],{},"Listen: a processz innentől blokkol.",[1027,1272,1273,706,1275,1277,1278,1280,1281,1284],{},[459,1274,705],{},[459,1276,709],{},"-re: a szerver nem fogad új kérést, és a ",[459,1279,689],{},"-on belül kivárja az in-flight kéréseket. Egy ",[480,1282,1283],{},"második"," signal azonnal öli a processzt.",[1027,1286,457,1287,1290,1291,1294],{},[459,1288,1289],{},"WithCloser","-rel regisztrált cleanupok ",[480,1292,1293],{},"LIFO"," sorrendben lefutnak (saját türelmi idővel, akkor is, ha a drain elfogyasztotta a keretet).",[1027,1296,1297],{},"Utolsóként a telemetria flush-ol: a closerekben keletkező spanok így még exportálódnak.",[455,1299,1300,1301,1303,1304,1306],{},"A pontos sorrendet és a signal-kezelés részleteit az ",[464,1302,130],{"href":131}," oldal írja le; ez az oldal azt mutatja, mit köt be a ",[459,1305,544],{}," erre a közös vázra.",[1308,1309,457,1310,1312],"note",{},[459,1311,556],{}," a teljes webszerver-konfigurációt hordozza: minden mező env-változóból töltődik be, típusosan, és a graceful shutdown nem egy külső process manager dolga, hanem a binárisé.",[547,1314,1316],{"id":1315},"mit-köt-be-a-serverrun","Mit köt be a server.Run",[500,1318,1320],{"className":502,"code":1319,"language":504,"meta":505,"style":505},"func Run(ctx context.Context, cfg Config, register RegisterFunc, opts ...Option) error\nfunc New(cfg Config, opts ...Option) *chi.Mux \u002F\u002F tesztekhez, speciális esetekre\n\ntype RegisterFunc func(r chi.Router) error\n",[459,1321,1322,1375,1412,1416],{"__ignoreMap":505},[509,1323,1324,1326,1329,1332,1335,1338,1340,1343,1346,1349,1351,1353,1356,1359,1361,1364,1367,1370,1372],{"class":511,"line":512},[509,1325,1095],{"class":519},[509,1327,1328],{"class":1110}," Run",[509,1330,1331],{"class":519},"(",[509,1333,1334],{"class":1101},"ctx",[509,1336,1337],{"class":523}," context",[509,1339,595],{"class":519},[509,1341,1342],{"class":523},"Context",[509,1344,1345],{"class":519},",",[509,1347,1348],{"class":1101}," cfg",[509,1350,577],{"class":523},[509,1352,1345],{"class":519},[509,1354,1355],{"class":1101}," register",[509,1357,1358],{"class":523}," RegisterFunc",[509,1360,1345],{"class":519},[509,1362,1363],{"class":1101}," opts",[509,1365,1366],{"class":519}," ...",[509,1368,1369],{"class":523},"Option",[509,1371,1107],{"class":519},[509,1373,1374],{"class":1117}," error\n",[509,1376,1377,1379,1382,1384,1387,1389,1391,1393,1395,1397,1399,1402,1404,1406,1409],{"class":511,"line":586},[509,1378,1095],{"class":519},[509,1380,1381],{"class":1110}," New",[509,1383,1331],{"class":519},[509,1385,1386],{"class":1101},"cfg",[509,1388,577],{"class":523},[509,1390,1345],{"class":519},[509,1392,1363],{"class":1101},[509,1394,1366],{"class":519},[509,1396,1369],{"class":523},[509,1398,1107],{"class":519},[509,1400,1401],{"class":519}," *",[509,1403,469],{"class":523},[509,1405,595],{"class":519},[509,1407,1408],{"class":523},"Mux",[509,1410,1411],{"class":626}," \u002F\u002F tesztekhez, speciális esetekre\n",[509,1413,1414],{"class":511,"line":601},[509,1415,1090],{"emptyLinePlaceholder":1089},[509,1417,1418,1420,1422,1425,1428,1431,1433,1436,1438],{"class":511,"line":623},[509,1419,574],{"class":519},[509,1421,1358],{"class":523},[509,1423,1424],{"class":519}," func(",[509,1426,1427],{"class":1101},"r",[509,1429,1430],{"class":523}," chi",[509,1432,595],{"class":519},[509,1434,1435],{"class":523},"Router",[509,1437,1107],{"class":519},[509,1439,1374],{"class":1117},[455,1441,457,1442,1445,1446,1448,1449,1452,1453,1456,1457,1460,1461,706,1463,1465,1466,1469,1470,1473,1474,1476,1477,1480],{},[459,1443,1444],{},"Run"," blokkol a kilépésig: telemetria bootstrap (",[459,1447,1221],{},") → router felépítése → ",[459,1450,1451],{},"register(r)"," → ",[459,1454,1455],{},"http.Server"," + ",[459,1458,1459],{},"ListenAndServe"," → graceful shutdown ",[459,1462,705],{},[459,1464,709],{},"-re. Tiszta leállásnál ",[459,1467,1468],{},"nil","-t ad vissza. A ",[459,1471,1472],{},"New"," a teljesen bekötött routert adja vissza futtatás és telemetria-bootstrap nélkül: a ",[459,1475,497],{},"-tel párosítod (lásd ",[464,1478,422],{"href":1479},"#tesztel%C3%A9s",").",[455,1482,1483,1484,1098,1487,1490,1491,1494],{},"A middleware-lánc egy ",[480,1485,1486],{},"nevesített, rendezett stack",[459,1488,1489],{},"server.Stack","), a framework defaultjaival előre feltöltve. Minden bejegyzésnek neve van; a neveket a ",[459,1492,1493],{},"server.MW*"," konstansok írják le, így egy elgépelt stack-mutáció fordítási hiba. A default sorrend, legkülsőtől befelé:",[638,1496,1497,1510],{},[641,1498,1499],{},[644,1500,1501,1504,1507],{},[647,1502,1503],{},"Név",[647,1505,1506],{},"Mikor aktív",[647,1508,1509],{},"Mit csinál",[660,1511,1512,1536,1562,1584,1602,1628,1652,1710,1733,1756],{},[644,1513,1514,1522,1525],{},[665,1515,1516,1098,1519,1107],{},[459,1517,1518],{},"requestid",[459,1520,1521],{},"MWRequestID",[665,1523,1524],{},"mindig",[665,1526,1527,1528,1531,1532,1535],{},"minden kérésnek azonosítót ad: egy jól formált bejövő ",[459,1529,1530],{},"X-Request-Id"," megmarad, egyébként UUID generálódik; a válasz-fejlécen visszaadja, a ",[459,1533,1534],{},"httpmw.RequestIDFromContext","-tel olvasható",[644,1537,1538,1545,1552],{},[665,1539,1540,1098,1542,1107],{},[459,1541,893],{},[459,1543,1544],{},"MWRealIP",[665,1546,1547,1548,1551],{},"csak ",[459,1549,1550],{},"HTTP_TRUST_PROXY=true"," mellett",[665,1553,890,1554,1556,1557,706,1559,1561],{},[459,1555,897],{},"-t az ",[459,1558,901],{},[459,1560,904],{},"-ból (első hop) írja át, így a logok és a Sentry a kliens címét látják a proxyé helyett",[644,1563,1564,1572,1578],{},[665,1565,1566,1098,1569,1107],{},[459,1567,1568],{},"otel",[459,1570,1571],{},"MWOtel",[665,1573,1574,1575,1551],{},"kivéve ",[459,1576,1577],{},"WithoutTelemetry",[665,1579,1580,1581,1583],{},"kérésenkénti szerver-span + HTTP-metrikák (",[464,1582,440],{"href":441},"); a span a recovery-t és a logolást is körbeöleli, így egy elkapott 500 a spanre kerül, az access-log rekordok pedig trace-kontextust hordoznak",[644,1585,1586,1594,1596],{},[665,1587,1588,1098,1591,1107],{},[459,1589,1590],{},"sentryhub",[459,1592,1593],{},"MWSentryHub",[665,1595,1524],{},[665,1597,1598,1599,1601],{},"kérésenkénti izolált Sentry hub, hogy a breadcrumbök ne keveredjenek kérések között; no-op, ha a ",[464,1600,445],{"href":446}," ki van kapcsolva",[644,1603,1604,1612,1614],{},[665,1605,1606,1098,1609,1107],{},[459,1607,1608],{},"recover",[459,1610,1611],{},"MWRecover",[665,1613,1524],{},[665,1615,1616,1617,1619,1620,1623,1624,1627],{},"egy panicból ",[459,1618,273],{}," hiba lesz, aminek a stackje a ",[480,1621,1622],{},"panic helyére"," mutat, és 500-as problem-válaszként renderelődik (az ",[459,1625,1626],{},"http.ErrAbortHandler","-t, a net\u002Fhttp flow-control szignálját, továbbengedi)",[644,1629,1630,1638,1643],{},[665,1631,1632,1098,1635,1107],{},[459,1633,1634],{},"validator",[459,1636,1637],{},"MWValidator",[665,1639,1547,1640,1551],{},[459,1641,1642],{},"WithValidator",[665,1644,890,1645,1647,1648,1651],{},[459,1646,1642],{},"-ral adott validátort a request contextbe teszi, ahol a ",[459,1649,1650],{},"StrictValidator(nil)"," megtalálja (lásd lent)",[644,1653,1654,1662,1671],{},[665,1655,1656,1098,1659,1107],{},[459,1657,1658],{},"accesslog",[459,1660,1661],{},"MWAccessLog",[665,1663,1664,1667,1668,1551],{},[459,1665,1666],{},"HTTP_ACCESS_LOG=true"," vagy ",[459,1669,1670],{},"OTEL_DEV_MODE=true",[665,1672,1673,1674,1676,1677,1200,1680,1200,1683,1686,1687,1200,1690,1200,1693,1200,1696,1200,1699,1702,1703,1705,1706,1709],{},"kérésenként egy strukturált ",[459,1675,1195],{}," rekord: ",[459,1678,1679],{},"method",[459,1681,1682],{},"path",[459,1684,1685],{},"route"," (a chi route-pattern), ",[459,1688,1689],{},"status",[459,1691,1692],{},"bytes",[459,1694,1695],{},"duration",[459,1697,1698],{},"remote",[459,1700,1701],{},"request_id","; 5xx error szinten; a ",[459,1704,1608],{},"-en belül ül, így egy panicoló kérés is logol (",[459,1707,1708],{},"panic=true","-val)",[644,1711,1712,1720,1722],{},[665,1713,1714,1098,1717,1107],{},[459,1715,1716],{},"cors",[459,1718,1719],{},"MWCORS",[665,1721,1524],{},[665,1723,890,1724,1200,1726,1200,1728,1165,1730,1732],{},[459,1725,803],{},[459,1727,823],{},[459,1729,843],{},[459,1731,863],{}," alapján",[644,1734,1735,1743,1745],{},[665,1736,1737,1098,1740,1107],{},[459,1738,1739],{},"bodylimit",[459,1741,1742],{},"MWBodyLimit",[665,1744,1524],{},[665,1746,1747,1748,1751,1752,1755],{},"a body-t ",[459,1749,1750],{},"http.MaxBytesReader","-be csomagolja ",[459,1753,1754],{},"cfg.EffectiveBodyLimit()","-tel: túllépésnél 413-as problem",[644,1757,1758,1765,1770],{},[665,1759,1760,1098,1762,1107],{},[459,1761,945],{},[459,1763,1764],{},"MWTimeout",[665,1766,1547,1767,1769],{},[459,1768,936],{}," > 0 mellett",[665,1771,1772],{},"a beállított idő után megszakítja a request contextet, a handlerhez legközelebb",[455,1774,1775,1776,1165,1779,1782,1783,1785,1786,1789,1790,898,1795,1798,1799,706,1802,1805],{},"Erre jönnek rá a ",[459,1777,1778],{},"WithMiddleware",[459,1780,1781],{},"WithStack"," extrák. Az ",[459,1784,205],{}," név (",[459,1787,1788],{},"MWAuth",") az identity middleware-nek van fenntartva arra az esetre, ha egy projekt a teljes stackre mountolja; a framework alapból nem telepít bejegyzést alá (az ",[464,1791,1792],{"href":212},[459,1793,1794],{},"add auth",[459,1796,1797],{},"api"," routeren köti be az identityt). A stack alatt a router ",[459,1800,1801],{},"NotFound",[459,1803,1804],{},"MethodNotAllowed"," kezelői a chi gyári plain-text hibái helyett 404\u002F405 problem+json választ adnak; a mountolt subrouterek öröklik őket.",[455,1807,1808,1809,1812,1813,1200,1816,1200,1819,1200,1822,1200,1825,1200,1828,1200,1830,1833,1834,1837],{},"A beépített bejegyzések maguk a ",[459,1810,1811],{},"gpsystem\u002Fhttpmw"," csomag exportált építőkockái (",[459,1814,1815],{},"RequestID",[459,1817,1818],{},"RealIP",[459,1820,1821],{},"Otel",[459,1823,1824],{},"RequestHub",[459,1826,1827],{},"Recoverer",[459,1829,912],{},[459,1831,1832],{},"CORSAPI",", ...), közösek a ",[464,1835,1836],{"href":145},"realtime gateway-jel",", így egy saját stack újrahasznosíthatja vagy újracsomagolhatja őket.",[455,1839,1840,1841,1843,1844,1847,1848,1850],{},"Két viselkedési megjegyzés. Minden válasz ",[459,1842,1530],{}," fejlécet hordoz, így egy support-ticket, egy log-rekord és egy trace ugyanarra a kérésre tud hivatkozni. A dev konzol kérés-logja pedig már nem a chi gyári ",[459,1845,1846],{},"Logger","-e, hanem a fenti strukturált access log (telemetria dev módban mindig aktív): az OTel ",[459,1849,1195],{}," bridge-dzsel a rekordjai trace-korreláltak.",[455,1852,457,1853,1855,1856,1858,1859,1200,1861,1200,1863,1200,1865,1480],{},[459,1854,556],{}," timeoutjai a ",[459,1857,1455],{},"-be fordulnak (",[459,1860,717],{},[459,1862,737],{},[459,1864,757],{},[459,1866,778],{},[1016,1868,1870],{"id":1869},"hibarenderelés-a-nethttp-ban-nincs-központi-error-handler","Hibarenderelés: a net\u002Fhttp-ban nincs központi error handler",[455,1872,1873],{},"A beépített error hookkal rendelkező frameworkökkel szemben a net\u002Fhttp nem ad módot arra, hogy egy handler „visszaadjon\" egy hibát a frameworknek: a handler maga írja meg a választ. A framework ezt három ponton hidalja át, hogy a drót-oldali viselkedés mindenhol egységes legyen:",[1024,1875,1876,1899,1905],{},[1027,1877,890,1878,1881,1882,1887,1888,1200,1891,1894,1895,1898],{},[480,1879,1880],{},"generált szerverkód hibahookjai"," a ",[464,1883,1884,1886],{"href":319},[459,1885,309],{}," net\u002Fhttp íróira"," vannak kötve (",[459,1889,1890],{},"WriteError",[459,1892,1893],{},"WriteBadRequest","): a handleredből visszaadott hiba így a ",[464,1896,1897],{"href":319},"teljes mappingen"," megy át;",[1027,1900,890,1901,1904],{},[480,1902,1903],{},"router-szintű esetek"," (panic, 404, 405, body limit) a fenti táblázat szerint problemként renderelődnek;",[1027,1906,890,1907,1910,1911,1914,1915,1918],{},[480,1908,1909],{},"kérés-validáció"," nem bind-time fut (a strict szerver ",[459,1912,1913],{},"json.Decoder","-rel dekódol), hanem a ",[459,1916,1917],{},"server.StrictValidator"," strict middleware-ben (lásd lent).",[547,1920,1922],{"id":1921},"a-shop-belépési-pontja","A shop belépési pontja",[455,1924,457,1925,1928],{},[464,1926,1927],{"href":32},"mintaalkalmazás"," HTTP-binárisa, amelynek minden sorát a generátor írta:",[500,1930,1933],{"className":502,"code":1931,"filename":1932,"language":504,"meta":505,"style":505},"package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com\u002Fgo-chi\u002Fchi\u002Fv5\"\n\n    \"github.com\u002Fgp-system\u002Fdbx\u002Fpg\"\n    \"github.com\u002Fgp-system\u002Fenvconf\"\n    \"github.com\u002Fgp-system\u002Fevents\u002Foutbox\"\n    \"github.com\u002Fgp-system\u002Fframework\u002Fserver\"\n\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig\"\n)\n\nfunc main() {\n    cfg := envconf.MustLoad[config.Config]()\n    ctx := context.Background()\n    pool := pg.MustNewPool(ctx, cfg.DB)\n\n    err := server.Run(ctx, cfg.Server, func(r chi.Router) error {\n        api := chi.NewRouter()\n        api.Use(server.IdentityMiddleware(cfg.JWT))\n        \u002F\u002F gpsystem:api-middleware\n        deps := shop.Dependencies{\n            DB:         pg.NewDB(pool),\n            Transactor: pg.NewTransactor(pool),\n            Dispatcher: outbox.NewDispatcher(outbox.NewStore(pg.NewDB(pool))),\n        }\n        shop.RegisterApi(api, deps)\n        shop.RegisterAdmin(api, deps)\n        r.Mount(\"\u002Fapi\u002Fv1\", api)\n        return nil\n    },\n        \u002F\u002F gpsystem:middleware\n        server.WithCloser(\"pgxpool\", func(context.Context) error {\n            pool.Close()\n            return nil\n        }),\n    )\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n","cmd\u002Fshop\u002Fmain.go",[459,1934,1935,1943,1947,1954,1964,1973,1978,1988,1993,2003,2013,2023,2032,2037,2047,2057,2063,2068,2080,2109,2127,2158,2163,2210,2227,2259,2265,2284,2309,2330,2372,2378,2400,2420,2448,2457,2463,2469,2504,2517,2525,2531,2537,2554,2572,2578],{"__ignoreMap":505},[509,1936,1937,1940],{"class":511,"line":512},[509,1938,1939],{"class":519},"package",[509,1941,1942],{"class":523}," main\n",[509,1944,1945],{"class":511,"line":586},[509,1946,1090],{"emptyLinePlaceholder":1089},[509,1948,1949,1951],{"class":511,"line":601},[509,1950,516],{"class":515},[509,1952,1953],{"class":519}," (\n",[509,1955,1956,1959,1962],{"class":511,"line":623},[509,1957,1958],{"class":519},"    \"",[509,1960,1961],{"class":523},"context",[509,1963,527],{"class":519},[509,1965,1966,1968,1971],{"class":511,"line":630},[509,1967,1958],{"class":519},[509,1969,1970],{"class":523},"log",[509,1972,527],{"class":519},[509,1974,1976],{"class":511,"line":1975},6,[509,1977,1090],{"emptyLinePlaceholder":1089},[509,1979,1981,1983,1986],{"class":511,"line":1980},7,[509,1982,1958],{"class":519},[509,1984,1985],{"class":523},"github.com\u002Fgo-chi\u002Fchi\u002Fv5",[509,1987,527],{"class":519},[509,1989,1991],{"class":511,"line":1990},8,[509,1992,1090],{"emptyLinePlaceholder":1089},[509,1994,1996,1998,2001],{"class":511,"line":1995},9,[509,1997,1958],{"class":519},[509,1999,2000],{"class":523},"github.com\u002Fgp-system\u002Fdbx\u002Fpg",[509,2002,527],{"class":519},[509,2004,2006,2008,2011],{"class":511,"line":2005},10,[509,2007,1958],{"class":519},[509,2009,2010],{"class":523},"github.com\u002Fgp-system\u002Fenvconf",[509,2012,527],{"class":519},[509,2014,2016,2018,2021],{"class":511,"line":2015},11,[509,2017,1958],{"class":519},[509,2019,2020],{"class":523},"github.com\u002Fgp-system\u002Fevents\u002Foutbox",[509,2022,527],{"class":519},[509,2024,2026,2028,2030],{"class":511,"line":2025},12,[509,2027,1958],{"class":519},[509,2029,524],{"class":523},[509,2031,527],{"class":519},[509,2033,2035],{"class":511,"line":2034},13,[509,2036,1090],{"emptyLinePlaceholder":1089},[509,2038,2040,2042,2045],{"class":511,"line":2039},14,[509,2041,1958],{"class":519},[509,2043,2044],{"class":523},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop",[509,2046,527],{"class":519},[509,2048,2050,2052,2055],{"class":511,"line":2049},15,[509,2051,1958],{"class":519},[509,2053,2054],{"class":523},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fplatform\u002Fconfig",[509,2056,527],{"class":519},[509,2058,2060],{"class":511,"line":2059},16,[509,2061,2062],{"class":519},")\n",[509,2064,2066],{"class":511,"line":2065},17,[509,2067,1090],{"emptyLinePlaceholder":1089},[509,2069,2071,2073,2076,2078],{"class":511,"line":2070},18,[509,2072,1095],{"class":519},[509,2074,2075],{"class":1110}," main",[509,2077,1114],{"class":519},[509,2079,583],{"class":519},[509,2081,2083,2086,2089,2092,2094,2097,2100,2102,2104,2106],{"class":511,"line":2082},19,[509,2084,2085],{"class":589},"    cfg ",[509,2087,2088],{"class":519},":=",[509,2090,2091],{"class":589}," envconf",[509,2093,595],{"class":519},[509,2095,2096],{"class":1110},"MustLoad",[509,2098,2099],{"class":519},"[",[509,2101,549],{"class":523},[509,2103,595],{"class":519},[509,2105,550],{"class":523},[509,2107,2108],{"class":519},"]()\n",[509,2110,2112,2115,2117,2119,2121,2124],{"class":511,"line":2111},20,[509,2113,2114],{"class":589},"    ctx ",[509,2116,2088],{"class":519},[509,2118,1337],{"class":589},[509,2120,595],{"class":519},[509,2122,2123],{"class":1110},"Background",[509,2125,2126],{"class":519},"()\n",[509,2128,2130,2133,2135,2138,2140,2143,2145,2147,2149,2151,2153,2156],{"class":511,"line":2129},21,[509,2131,2132],{"class":589},"    pool ",[509,2134,2088],{"class":519},[509,2136,2137],{"class":589}," pg",[509,2139,595],{"class":519},[509,2141,2142],{"class":1110},"MustNewPool",[509,2144,1331],{"class":519},[509,2146,1334],{"class":589},[509,2148,1345],{"class":519},[509,2150,1348],{"class":589},[509,2152,595],{"class":519},[509,2154,2155],{"class":589},"DB",[509,2157,2062],{"class":519},[509,2159,2161],{"class":511,"line":2160},22,[509,2162,1090],{"emptyLinePlaceholder":1089},[509,2164,2166,2169,2171,2174,2176,2178,2180,2182,2184,2186,2188,2191,2193,2195,2197,2199,2201,2203,2205,2208],{"class":511,"line":2165},23,[509,2167,2168],{"class":589},"    err ",[509,2170,2088],{"class":519},[509,2172,2173],{"class":589}," server",[509,2175,595],{"class":519},[509,2177,1444],{"class":1110},[509,2179,1331],{"class":519},[509,2181,1334],{"class":589},[509,2183,1345],{"class":519},[509,2185,1348],{"class":589},[509,2187,595],{"class":519},[509,2189,2190],{"class":589},"Server",[509,2192,1345],{"class":519},[509,2194,1424],{"class":519},[509,2196,1427],{"class":1101},[509,2198,1430],{"class":523},[509,2200,595],{"class":519},[509,2202,1435],{"class":523},[509,2204,1107],{"class":519},[509,2206,2207],{"class":1117}," error",[509,2209,583],{"class":519},[509,2211,2213,2216,2218,2220,2222,2225],{"class":511,"line":2212},24,[509,2214,2215],{"class":589},"        api ",[509,2217,2088],{"class":519},[509,2219,1430],{"class":589},[509,2221,595],{"class":519},[509,2223,2224],{"class":1110},"NewRouter",[509,2226,2126],{"class":519},[509,2228,2230,2233,2235,2238,2240,2242,2244,2247,2249,2251,2253,2256],{"class":511,"line":2229},25,[509,2231,2232],{"class":589},"        api",[509,2234,595],{"class":519},[509,2236,2237],{"class":1110},"Use",[509,2239,1331],{"class":519},[509,2241,461],{"class":589},[509,2243,595],{"class":519},[509,2245,2246],{"class":1110},"IdentityMiddleware",[509,2248,1331],{"class":519},[509,2250,1386],{"class":589},[509,2252,595],{"class":519},[509,2254,2255],{"class":589},"JWT",[509,2257,2258],{"class":519},"))\n",[509,2260,2262],{"class":511,"line":2261},26,[509,2263,2264],{"class":626},"        \u002F\u002F gpsystem:api-middleware\n",[509,2266,2268,2271,2273,2276,2278,2281],{"class":511,"line":2267},27,[509,2269,2270],{"class":589},"        deps ",[509,2272,2088],{"class":519},[509,2274,2275],{"class":523}," shop",[509,2277,595],{"class":519},[509,2279,2280],{"class":523},"Dependencies",[509,2282,2283],{"class":519},"{\n",[509,2285,2287,2290,2293,2296,2298,2301,2303,2306],{"class":511,"line":2286},28,[509,2288,2289],{"class":589},"            DB",[509,2291,2292],{"class":519},":",[509,2294,2295],{"class":589},"         pg",[509,2297,595],{"class":519},[509,2299,2300],{"class":1110},"NewDB",[509,2302,1331],{"class":519},[509,2304,2305],{"class":589},"pool",[509,2307,2308],{"class":519},"),\n",[509,2310,2312,2315,2317,2319,2321,2324,2326,2328],{"class":511,"line":2311},29,[509,2313,2314],{"class":589},"            Transactor",[509,2316,2292],{"class":519},[509,2318,2137],{"class":589},[509,2320,595],{"class":519},[509,2322,2323],{"class":1110},"NewTransactor",[509,2325,1331],{"class":519},[509,2327,2305],{"class":589},[509,2329,2308],{"class":519},[509,2331,2333,2336,2338,2341,2343,2346,2348,2351,2353,2356,2358,2361,2363,2365,2367,2369],{"class":511,"line":2332},30,[509,2334,2335],{"class":589},"            Dispatcher",[509,2337,2292],{"class":519},[509,2339,2340],{"class":589}," outbox",[509,2342,595],{"class":519},[509,2344,2345],{"class":1110},"NewDispatcher",[509,2347,1331],{"class":519},[509,2349,2350],{"class":589},"outbox",[509,2352,595],{"class":519},[509,2354,2355],{"class":1110},"NewStore",[509,2357,1331],{"class":519},[509,2359,2360],{"class":589},"pg",[509,2362,595],{"class":519},[509,2364,2300],{"class":1110},[509,2366,1331],{"class":519},[509,2368,2305],{"class":589},[509,2370,2371],{"class":519},"))),\n",[509,2373,2375],{"class":511,"line":2374},31,[509,2376,2377],{"class":519},"        }\n",[509,2379,2381,2384,2386,2389,2391,2393,2395,2398],{"class":511,"line":2380},32,[509,2382,2383],{"class":589},"        shop",[509,2385,595],{"class":519},[509,2387,2388],{"class":1110},"RegisterApi",[509,2390,1331],{"class":519},[509,2392,1797],{"class":589},[509,2394,1345],{"class":519},[509,2396,2397],{"class":589}," deps",[509,2399,2062],{"class":519},[509,2401,2403,2405,2407,2410,2412,2414,2416,2418],{"class":511,"line":2402},33,[509,2404,2383],{"class":589},[509,2406,595],{"class":519},[509,2408,2409],{"class":1110},"RegisterAdmin",[509,2411,1331],{"class":519},[509,2413,1797],{"class":589},[509,2415,1345],{"class":519},[509,2417,2397],{"class":589},[509,2419,2062],{"class":519},[509,2421,2423,2426,2428,2431,2433,2436,2439,2441,2443,2446],{"class":511,"line":2422},34,[509,2424,2425],{"class":589},"        r",[509,2427,595],{"class":519},[509,2429,2430],{"class":1110},"Mount",[509,2432,1331],{"class":519},[509,2434,2435],{"class":519},"\"",[509,2437,2438],{"class":616},"\u002Fapi\u002Fv1",[509,2440,2435],{"class":519},[509,2442,1345],{"class":519},[509,2444,2445],{"class":589}," api",[509,2447,2062],{"class":519},[509,2449,2451,2454],{"class":511,"line":2450},35,[509,2452,2453],{"class":515},"        return",[509,2455,2456],{"class":519}," nil\n",[509,2458,2460],{"class":511,"line":2459},36,[509,2461,2462],{"class":519},"    },\n",[509,2464,2466],{"class":511,"line":2465},37,[509,2467,2468],{"class":626},"        \u002F\u002F gpsystem:middleware\n",[509,2470,2472,2475,2477,2479,2481,2483,2486,2488,2490,2492,2494,2496,2498,2500,2502],{"class":511,"line":2471},38,[509,2473,2474],{"class":589},"        server",[509,2476,595],{"class":519},[509,2478,1289],{"class":1110},[509,2480,1331],{"class":519},[509,2482,2435],{"class":519},[509,2484,2485],{"class":616},"pgxpool",[509,2487,2435],{"class":519},[509,2489,1345],{"class":519},[509,2491,1424],{"class":519},[509,2493,1961],{"class":523},[509,2495,595],{"class":519},[509,2497,1342],{"class":523},[509,2499,1107],{"class":519},[509,2501,2207],{"class":1117},[509,2503,583],{"class":519},[509,2505,2507,2510,2512,2515],{"class":511,"line":2506},39,[509,2508,2509],{"class":589},"            pool",[509,2511,595],{"class":519},[509,2513,2514],{"class":1110},"Close",[509,2516,2126],{"class":519},[509,2518,2520,2523],{"class":511,"line":2519},40,[509,2521,2522],{"class":515},"            return",[509,2524,2456],{"class":519},[509,2526,2528],{"class":511,"line":2527},41,[509,2529,2530],{"class":519},"        }),\n",[509,2532,2534],{"class":511,"line":2533},42,[509,2535,2536],{"class":519},"    )\n",[509,2538,2540,2543,2546,2549,2552],{"class":511,"line":2539},43,[509,2541,2542],{"class":515},"    if",[509,2544,2545],{"class":589}," err ",[509,2547,2548],{"class":519},"!=",[509,2550,2551],{"class":519}," nil",[509,2553,583],{"class":519},[509,2555,2557,2560,2562,2565,2567,2570],{"class":511,"line":2556},44,[509,2558,2559],{"class":589},"        log",[509,2561,595],{"class":519},[509,2563,2564],{"class":1110},"Fatal",[509,2566,1331],{"class":519},[509,2568,2569],{"class":589},"err",[509,2571,2062],{"class":519},[509,2573,2575],{"class":511,"line":2574},45,[509,2576,2577],{"class":519},"    }\n",[509,2579,2581],{"class":511,"line":2580},46,[509,2582,633],{"class":519},[455,2584,2585,2586,2588,2589,2591,2592,2595,2596,2600,2601,2604,2605,2608,2609,706,2611,2613],{},"A prefixelés ",[459,2587,2430],{},"-tal történik: minden modul surface-ei egy friss subrouterre regisztrálnak, ami a ",[459,2590,2438],{}," alá mountolódik. A két anchor-komment middleware-varrat: a fölöttük álló ",[459,2593,2594],{},"api.Use(server.IdentityMiddleware(cfg.JWT))"," sort az ",[464,2597,2598],{"href":212},[459,2599,1794],{}," szúrta be a ",[459,2602,2603],{},"gpsystem:api-middleware","-nél, a ",[459,2606,2607],{},"gpsystem:middleware"," pedig azt jelöli, hova kerülnek a ",[459,2610,1781],{},[459,2612,1778],{}," opciók az opciólistában.",[1016,2615,2617],{"id":2616},"opciók","Opciók",[500,2619,2621],{"className":502,"code":2620,"language":504,"meta":505,"style":505},"server.WithCloser(\"pgxpool\", func(ctx context.Context) error { pool.Close(); return nil })\nserver.WithMiddleware(myRateLimiter)                       \u002F\u002F ...func(http.Handler) http.Handler\nserver.WithStack(func(s *server.Stack) {                   \u002F\u002F sebészet a nevesített láncon\n    s.InsertBefore(server.MWCORS, \"tenant\", tenantMW)\n    s.Remove(server.MWSentryHub)\n})\nserver.WithHTTPServer(func(s *http.Server) { s.MaxHeaderBytes = 1 \u003C\u003C 16 })\nserver.WithValidator(validate.New(validate.WithRegister(registerCustomTags)))\nserver.WithoutTelemetry()                                  \u002F\u002F tesztek \u002F külső OTel setup\n",[459,2622,2623,2676,2694,2724,2758,2777,2782,2828,2862],{"__ignoreMap":505},[509,2624,2625,2627,2629,2631,2633,2635,2637,2639,2641,2643,2645,2647,2649,2651,2653,2655,2658,2661,2663,2665,2668,2671,2673],{"class":511,"line":512},[509,2626,461],{"class":589},[509,2628,595],{"class":519},[509,2630,1289],{"class":1110},[509,2632,1331],{"class":519},[509,2634,2435],{"class":519},[509,2636,2485],{"class":616},[509,2638,2435],{"class":519},[509,2640,1345],{"class":519},[509,2642,1424],{"class":519},[509,2644,1334],{"class":1101},[509,2646,1337],{"class":523},[509,2648,595],{"class":519},[509,2650,1342],{"class":523},[509,2652,1107],{"class":519},[509,2654,2207],{"class":1117},[509,2656,2657],{"class":519}," {",[509,2659,2660],{"class":589}," pool",[509,2662,595],{"class":519},[509,2664,2514],{"class":1110},[509,2666,2667],{"class":519},"();",[509,2669,2670],{"class":515}," return",[509,2672,2551],{"class":519},[509,2674,2675],{"class":519}," })\n",[509,2677,2678,2680,2682,2684,2686,2689,2691],{"class":511,"line":586},[509,2679,461],{"class":589},[509,2681,595],{"class":519},[509,2683,1778],{"class":1110},[509,2685,1331],{"class":519},[509,2687,2688],{"class":589},"myRateLimiter",[509,2690,1107],{"class":519},[509,2692,2693],{"class":626},"                       \u002F\u002F ...func(http.Handler) http.Handler\n",[509,2695,2696,2698,2700,2702,2705,2708,2710,2712,2714,2717,2719,2721],{"class":511,"line":601},[509,2697,461],{"class":589},[509,2699,595],{"class":519},[509,2701,1781],{"class":1110},[509,2703,2704],{"class":519},"(func(",[509,2706,2707],{"class":1101},"s",[509,2709,1401],{"class":519},[509,2711,461],{"class":523},[509,2713,595],{"class":519},[509,2715,2716],{"class":523},"Stack",[509,2718,1107],{"class":519},[509,2720,2657],{"class":519},[509,2722,2723],{"class":626},"                   \u002F\u002F sebészet a nevesített láncon\n",[509,2725,2726,2729,2731,2734,2736,2738,2740,2742,2744,2746,2749,2751,2753,2756],{"class":511,"line":623},[509,2727,2728],{"class":589},"    s",[509,2730,595],{"class":519},[509,2732,2733],{"class":1110},"InsertBefore",[509,2735,1331],{"class":519},[509,2737,461],{"class":589},[509,2739,595],{"class":519},[509,2741,1719],{"class":589},[509,2743,1345],{"class":519},[509,2745,520],{"class":519},[509,2747,2748],{"class":616},"tenant",[509,2750,2435],{"class":519},[509,2752,1345],{"class":519},[509,2754,2755],{"class":589}," tenantMW",[509,2757,2062],{"class":519},[509,2759,2760,2762,2764,2767,2769,2771,2773,2775],{"class":511,"line":630},[509,2761,2728],{"class":589},[509,2763,595],{"class":519},[509,2765,2766],{"class":1110},"Remove",[509,2768,1331],{"class":519},[509,2770,461],{"class":589},[509,2772,595],{"class":519},[509,2774,1593],{"class":589},[509,2776,2062],{"class":519},[509,2778,2779],{"class":511,"line":1975},[509,2780,2781],{"class":519},"})\n",[509,2783,2784,2786,2788,2791,2793,2795,2797,2800,2802,2804,2806,2808,2811,2813,2816,2818,2821,2823,2826],{"class":511,"line":1980},[509,2785,461],{"class":589},[509,2787,595],{"class":519},[509,2789,2790],{"class":1110},"WithHTTPServer",[509,2792,2704],{"class":519},[509,2794,2707],{"class":1101},[509,2796,1401],{"class":519},[509,2798,2799],{"class":523},"http",[509,2801,595],{"class":519},[509,2803,2190],{"class":523},[509,2805,1107],{"class":519},[509,2807,2657],{"class":519},[509,2809,2810],{"class":589}," s",[509,2812,595],{"class":519},[509,2814,2815],{"class":589},"MaxHeaderBytes ",[509,2817,1071],{"class":519},[509,2819,2820],{"class":1074}," 1",[509,2822,1078],{"class":519},[509,2824,2825],{"class":1074}," 16",[509,2827,2675],{"class":519},[509,2829,2830,2832,2834,2836,2838,2841,2843,2845,2847,2849,2851,2854,2856,2859],{"class":511,"line":1990},[509,2831,461],{"class":589},[509,2833,595],{"class":519},[509,2835,1642],{"class":1110},[509,2837,1331],{"class":519},[509,2839,2840],{"class":589},"validate",[509,2842,595],{"class":519},[509,2844,1472],{"class":1110},[509,2846,1331],{"class":519},[509,2848,2840],{"class":589},[509,2850,595],{"class":519},[509,2852,2853],{"class":1110},"WithRegister",[509,2855,1331],{"class":519},[509,2857,2858],{"class":589},"registerCustomTags",[509,2860,2861],{"class":519},")))\n",[509,2863,2864,2866,2868,2870,2872],{"class":511,"line":1995},[509,2865,461],{"class":589},[509,2867,595],{"class":519},[509,2869,1577],{"class":1110},[509,2871,1114],{"class":519},[509,2873,2874],{"class":626},"                                  \u002F\u002F tesztek \u002F külső OTel setup\n",[1024,2876,2877,2888,2900,2931,2946,2962],{},[1027,2878,2879,2884,2885,2887],{},[480,2880,2881],{},[459,2882,2883],{},"WithCloser(name, fn)",": cleanup graceful shutdownkor, miután a szerver már nem fogad kérést. A closerek ",[480,2886,1293],{}," sorrendben futnak; a telemetria utolsóként flush-ol, így egy closerben emittált span még exportálódik.",[1027,2889,2890,2895,2896,2899],{},[480,2891,2892],{},[459,2893,2894],{},"WithMiddleware(...func(http.Handler) http.Handler)",": router-szintű middleware, a framework defaultjai után fűzve. A standard net\u002Fhttp middleware-forma: bármely ökoszisztéma-middleware ide passzol. Ami csak egy surface-re kell, azt a surface ",[459,2897,2898],{},"Route","-jára tedd (lásd lent).",[1027,2901,2902,2907,2908,2910,2911,2914,2915,2918,2919,2922,2923,2926,2927,2930],{},[480,2903,2904],{},[459,2905,2906],{},"WithStack(func(*server.Stack))",": minden, amit a ",[459,2909,1778],{}," nem tud: beszúrás egy nevesített default elé vagy mögé (",[459,2912,2913],{},"s.InsertBefore(server.MWCORS, \"tenant\", tenantMW)","), implementáció-csere (",[459,2916,2917],{},"Replace","), vagy egy default eldobása (",[459,2920,2921],{},"s.Remove(server.MWSentryHub)","; egy nem létező név eltávolítása no-op, így a feltételes defaultok feltétel nélkül eltávolíthatók). A mutációk ismeretlen célra vagy duplikált névre ",[480,2924,2925],{},"panicelnek",": egy bekötési hiba bootkor bukik el, nem kérés-időben. A ",[459,2928,2929],{},"Names()"," a lánc sorrendjét adja vissza, tesztekhez.",[1027,2932,2933,2938,2939,2941,2942,2945],{},[480,2934,2935],{},[459,2936,2937],{},"WithHTTPServer(func(*http.Server))",": escape hatch a ",[459,2940,1455],{}," azon mezőihez, amiket a framework nem exponál (TLS, ",[459,2943,2944],{},"MaxHeaderBytes",", ...). A framework által beállított mezőket is felülírhatod: a te mutációd fut utoljára.",[1027,2947,2948,2953,2954,2958,2959,2961],{},[480,2949,2950],{},[459,2951,2952],{},"WithValidator(*validate.Validator)",": az alkalmazás-szintű request-validátor, tipikusan ",[464,2955,2957],{"href":2956},"\u002Fhu\u002Fhttperr\u002Fvalidation#saj%C3%A1t-tagek","saját validációs tagekkel","; a ",[459,2960,1650],{}," middleware-ek request-időben ezt oldják fel.",[1027,2963,2964,2969,2970,2972],{},[480,2965,2966],{},[459,2967,2968],{},"WithoutTelemetry()",": kihagyja az ",[459,2971,1221],{},"-t és az OTel middleware-t; tesztekhez, vagy ha a processz maga konfigurálja a telemetriát.",[547,2974,2976],{"id":2975},"registerfunc-és-strictvalidator","RegisterFunc és StrictValidator",[455,2978,2979,2980,2984,2985,2988,2989,2992,2993,2995],{},"Az ",[464,2981,2982],{"href":92},[459,2983,91],{}," surface-enként egy ",[459,2986,2987],{},"Register\u003CSurface>"," függvényt illeszt a modul ",[459,2990,2991],{},"register.go","-jába. A shop ",[459,2994,1797],{}," surface-ére szó szerint ez generálódik:",[500,2997,3000],{"className":502,"code":2998,"filename":2999,"language":504,"meta":505,"style":505},"func RegisterApi(router chi.Router, deps Dependencies) {\n    apiSvc := apiservice.New()\n    apiHandler := apihttp.New(apiSvc)\n    apiPolicies := apipolicy.New()\n    router.Route(\"\u002Fshop\", func(r chi.Router) {\n        \u002F\u002F gpsystem:surface-middleware\n        shopapigen.HandlerWithOptions(shopapigen.NewStrictHandlerWithOptions(\n            apiHandler,\n            []shopapigen.StrictMiddlewareFunc{\n                server.StrictValidator[shopapigen.StrictHandlerFunc](nil),\n                \u002F\u002F Az utolsó a legkülső: az authorizáció a validáció előtt fut.\n                kitpolicy.Enforcer[shopapigen.StrictHandlerFunc](apiPolicies, shopapigen.PermissionByOperation, shopapigen.PolicyByOperation),\n            },\n            shopapigen.StrictHTTPServerOptions{\n                RequestErrorHandlerFunc:  httperr.WriteBadRequest,\n                ResponseErrorHandlerFunc: server.WriteError,\n            },\n        ), shopapigen.ChiServerOptions{\n            BaseRouter:       r,\n            ErrorHandlerFunc: httperr.WriteBadRequest,\n        })\n    })\n}\n","internal\u002Fmodules\u002Fshop\u002Fregister.go",[459,3001,3002,3031,3047,3068,3084,3118,3123,3146,3154,3168,3190,3195,3240,3245,3257,3273,3288,3292,3306,3318,3334,3339,3344],{"__ignoreMap":505},[509,3003,3004,3006,3009,3011,3014,3016,3018,3020,3022,3024,3027,3029],{"class":511,"line":512},[509,3005,1095],{"class":519},[509,3007,3008],{"class":1110}," RegisterApi",[509,3010,1331],{"class":519},[509,3012,3013],{"class":1101},"router",[509,3015,1430],{"class":523},[509,3017,595],{"class":519},[509,3019,1435],{"class":523},[509,3021,1345],{"class":519},[509,3023,2397],{"class":1101},[509,3025,3026],{"class":523}," Dependencies",[509,3028,1107],{"class":519},[509,3030,583],{"class":519},[509,3032,3033,3036,3038,3041,3043,3045],{"class":511,"line":586},[509,3034,3035],{"class":589},"    apiSvc ",[509,3037,2088],{"class":519},[509,3039,3040],{"class":589}," apiservice",[509,3042,595],{"class":519},[509,3044,1472],{"class":1110},[509,3046,2126],{"class":519},[509,3048,3049,3052,3054,3057,3059,3061,3063,3066],{"class":511,"line":601},[509,3050,3051],{"class":589},"    apiHandler ",[509,3053,2088],{"class":519},[509,3055,3056],{"class":589}," apihttp",[509,3058,595],{"class":519},[509,3060,1472],{"class":1110},[509,3062,1331],{"class":519},[509,3064,3065],{"class":589},"apiSvc",[509,3067,2062],{"class":519},[509,3069,3070,3073,3075,3078,3080,3082],{"class":511,"line":623},[509,3071,3072],{"class":589},"    apiPolicies ",[509,3074,2088],{"class":519},[509,3076,3077],{"class":589}," apipolicy",[509,3079,595],{"class":519},[509,3081,1472],{"class":1110},[509,3083,2126],{"class":519},[509,3085,3086,3089,3091,3093,3095,3097,3100,3102,3104,3106,3108,3110,3112,3114,3116],{"class":511,"line":630},[509,3087,3088],{"class":589},"    router",[509,3090,595],{"class":519},[509,3092,2898],{"class":1110},[509,3094,1331],{"class":519},[509,3096,2435],{"class":519},[509,3098,3099],{"class":616},"\u002Fshop",[509,3101,2435],{"class":519},[509,3103,1345],{"class":519},[509,3105,1424],{"class":519},[509,3107,1427],{"class":1101},[509,3109,1430],{"class":523},[509,3111,595],{"class":519},[509,3113,1435],{"class":523},[509,3115,1107],{"class":519},[509,3117,583],{"class":519},[509,3119,3120],{"class":511,"line":1975},[509,3121,3122],{"class":626},"        \u002F\u002F gpsystem:surface-middleware\n",[509,3124,3125,3128,3130,3133,3135,3138,3140,3143],{"class":511,"line":1980},[509,3126,3127],{"class":589},"        shopapigen",[509,3129,595],{"class":519},[509,3131,3132],{"class":1110},"HandlerWithOptions",[509,3134,1331],{"class":519},[509,3136,3137],{"class":589},"shopapigen",[509,3139,595],{"class":519},[509,3141,3142],{"class":1110},"NewStrictHandlerWithOptions",[509,3144,3145],{"class":519},"(\n",[509,3147,3148,3151],{"class":511,"line":1990},[509,3149,3150],{"class":589},"            apiHandler",[509,3152,3153],{"class":519},",\n",[509,3155,3156,3159,3161,3163,3166],{"class":511,"line":1995},[509,3157,3158],{"class":519},"            []",[509,3160,3137],{"class":523},[509,3162,595],{"class":519},[509,3164,3165],{"class":523},"StrictMiddlewareFunc",[509,3167,2283],{"class":519},[509,3169,3170,3173,3175,3178,3180,3182,3184,3187],{"class":511,"line":2005},[509,3171,3172],{"class":589},"                server",[509,3174,595],{"class":519},[509,3176,3177],{"class":1110},"StrictValidator",[509,3179,2099],{"class":519},[509,3181,3137],{"class":523},[509,3183,595],{"class":519},[509,3185,3186],{"class":523},"StrictHandlerFunc",[509,3188,3189],{"class":519},"](nil),\n",[509,3191,3192],{"class":511,"line":2015},[509,3193,3194],{"class":626},"                \u002F\u002F Az utolsó a legkülső: az authorizáció a validáció előtt fut.\n",[509,3196,3197,3200,3202,3205,3207,3209,3211,3213,3216,3219,3221,3224,3226,3229,3231,3233,3235,3238],{"class":511,"line":2025},[509,3198,3199],{"class":589},"                kitpolicy",[509,3201,595],{"class":519},[509,3203,3204],{"class":1110},"Enforcer",[509,3206,2099],{"class":519},[509,3208,3137],{"class":523},[509,3210,595],{"class":519},[509,3212,3186],{"class":523},[509,3214,3215],{"class":519},"](",[509,3217,3218],{"class":589},"apiPolicies",[509,3220,1345],{"class":519},[509,3222,3223],{"class":589}," shopapigen",[509,3225,595],{"class":519},[509,3227,3228],{"class":589},"PermissionByOperation",[509,3230,1345],{"class":519},[509,3232,3223],{"class":589},[509,3234,595],{"class":519},[509,3236,3237],{"class":589},"PolicyByOperation",[509,3239,2308],{"class":519},[509,3241,3242],{"class":511,"line":2034},[509,3243,3244],{"class":519},"            },\n",[509,3246,3247,3250,3252,3255],{"class":511,"line":2039},[509,3248,3249],{"class":523},"            shopapigen",[509,3251,595],{"class":519},[509,3253,3254],{"class":523},"StrictHTTPServerOptions",[509,3256,2283],{"class":519},[509,3258,3259,3262,3264,3267,3269,3271],{"class":511,"line":2049},[509,3260,3261],{"class":589},"                RequestErrorHandlerFunc",[509,3263,2292],{"class":519},[509,3265,3266],{"class":589},"  httperr",[509,3268,595],{"class":519},[509,3270,1893],{"class":589},[509,3272,3153],{"class":519},[509,3274,3275,3278,3280,3282,3284,3286],{"class":511,"line":2059},[509,3276,3277],{"class":589},"                ResponseErrorHandlerFunc",[509,3279,2292],{"class":519},[509,3281,2173],{"class":589},[509,3283,595],{"class":519},[509,3285,1890],{"class":589},[509,3287,3153],{"class":519},[509,3289,3290],{"class":511,"line":2065},[509,3291,3244],{"class":519},[509,3293,3294,3297,3299,3301,3304],{"class":511,"line":2070},[509,3295,3296],{"class":519},"        ),",[509,3298,3223],{"class":523},[509,3300,595],{"class":519},[509,3302,3303],{"class":523},"ChiServerOptions",[509,3305,2283],{"class":519},[509,3307,3308,3311,3313,3316],{"class":511,"line":2082},[509,3309,3310],{"class":589},"            BaseRouter",[509,3312,2292],{"class":519},[509,3314,3315],{"class":589},"       r",[509,3317,3153],{"class":519},[509,3319,3320,3323,3325,3328,3330,3332],{"class":511,"line":2111},[509,3321,3322],{"class":589},"            ErrorHandlerFunc",[509,3324,2292],{"class":519},[509,3326,3327],{"class":589}," httperr",[509,3329,595],{"class":519},[509,3331,1893],{"class":589},[509,3333,3153],{"class":519},[509,3335,3336],{"class":511,"line":2129},[509,3337,3338],{"class":519},"        })\n",[509,3340,3341],{"class":511,"line":2160},[509,3342,3343],{"class":519},"    })\n",[509,3345,3346],{"class":511,"line":2165},[509,3347,633],{"class":519},[455,3349,3350],{},"Sorról sorra:",[1254,3352,3353,3359,3377,3422],{},[1027,3354,3355,3358],{},[480,3356,3357],{},"Service → handler → policy registry",": explicit felépítés, container nélkül.",[1027,3360,3361,3366,3367,3369,3370,3373,3374,1480],{},[480,3362,3363],{},[459,3364,3365],{},"router.Route(\"\u002Fshop\", ...)",": az ",[459,3368,1797],{}," surface a modul gyökerére kerül (",[459,3371,3372],{},"\u002Fapi\u002Fv1\u002Fshop\u002F...","); minden más surface a saját prefixe alá (",[459,3375,3376],{},"\u002Fadmin\u002Fshop",[1027,3378,3379,3383,3384,3386,3387,1200,3390,3393,3394,3397,3398,3393,3401,3404,3405,706,3407,706,3410,3413,3414,3417,3418,3421],{},[480,3380,3381],{},[459,3382,3142],{},": a ",[464,3385,533],{"href":196}," strict szerver, plusz a hibahookok: a request-dekódolási hibák (",[459,3388,3389],{},"RequestErrorHandlerFunc",[459,3391,3392],{},"ErrorHandlerFunc",") ",[459,3395,3396],{},"httperr.WriteBadRequest","-en át 400-ként, a handlered hibái (",[459,3399,3400],{},"ResponseErrorHandlerFunc",[459,3402,3403],{},"server.WriteError","-on át renderelődnek, ami az ",[459,3406,205],{},[459,3408,3409],{},"rbac",[459,3411,3412],{},"policy"," sentineleket Problemre képezi, mindent mást pedig a ",[459,3415,3416],{},"httperr.WriteError","-ra delegál, a ",[464,3419,3420],{"href":319},"teljes mapping"," szerint.",[1027,3423,3424,3431,3432,3435],{},[480,3425,3426,1456,3428],{},[459,3427,1917],{},[459,3429,3430],{},"kitpolicy.Enforcer",": validáció és ",[464,3433,3434],{"href":222},"policy-érvényesítés"," strict middleware-ként; a lista utolsó eleme fut legkívül, ezért az enforcer megelőzi a validátort.",[1016,3437,3439],{"id":3438},"strictvalidator-validáció-a-handler-előtt","StrictValidator: validáció a handler előtt",[500,3441,3443],{"className":502,"code":3442,"language":504,"meta":505,"style":505},"func StrictValidator[H ~func(ctx context.Context, w http.ResponseWriter, r *http.Request, request any) (any, error)](\n    v *validate.Validator,\n) func(f H, operationID string) H\n",[459,3444,3445,3517,3533],{"__ignoreMap":505},[509,3446,3447,3449,3452,3454,3457,3460,3462,3464,3466,3468,3470,3473,3476,3478,3481,3483,3486,3488,3490,3492,3495,3497,3500,3503,3505,3507,3510,3512,3514],{"class":511,"line":512},[509,3448,1095],{"class":519},[509,3450,3451],{"class":1110}," StrictValidator",[509,3453,2099],{"class":519},[509,3455,3456],{"class":1101},"H",[509,3458,3459],{"class":519}," ~func(",[509,3461,1334],{"class":1101},[509,3463,1337],{"class":523},[509,3465,595],{"class":519},[509,3467,1342],{"class":523},[509,3469,1345],{"class":519},[509,3471,3472],{"class":1101}," w",[509,3474,3475],{"class":523}," http",[509,3477,595],{"class":519},[509,3479,3480],{"class":523},"ResponseWriter",[509,3482,1345],{"class":519},[509,3484,3485],{"class":1101}," r",[509,3487,1401],{"class":519},[509,3489,2799],{"class":523},[509,3491,595],{"class":519},[509,3493,3494],{"class":523},"Request",[509,3496,1345],{"class":519},[509,3498,3499],{"class":1101}," request",[509,3501,3502],{"class":523}," any",[509,3504,1107],{"class":519},[509,3506,1098],{"class":519},[509,3508,3509],{"class":523},"any",[509,3511,1345],{"class":519},[509,3513,2207],{"class":1117},[509,3515,3516],{"class":519},")](\n",[509,3518,3519,3522,3524,3526,3528,3531],{"class":511,"line":586},[509,3520,3521],{"class":1101},"    v",[509,3523,1401],{"class":519},[509,3525,2840],{"class":523},[509,3527,595],{"class":519},[509,3529,3530],{"class":523},"Validator",[509,3532,3153],{"class":519},[509,3534,3535,3537,3539,3542,3545,3547,3550,3553,3555],{"class":511,"line":601},[509,3536,1107],{"class":519},[509,3538,1424],{"class":519},[509,3540,3541],{"class":1101},"f",[509,3543,3544],{"class":523}," H",[509,3546,1345],{"class":519},[509,3548,3549],{"class":1101}," operationID",[509,3551,3552],{"class":1117}," string",[509,3554,1107],{"class":519},[509,3556,3557],{"class":523}," H\n",[455,3559,3560,3561,3563,3564,3566,3567,3569,3570,3572],{},"A strict szerver ",[459,3562,1913],{},"-rel dekódol, validáció nélkül. A ",[459,3565,3177],{}," ezt a rést zárja: a teljesen bekötött request objektumot (paraméterek + body) validálja a framework validátorával, mielőtt a handlered futna; bukásnál 422 problem a ",[459,3568,3400],{},"-on át. A típusparaméter azért kell, mert az oapi-codegen a ",[459,3571,3186],{},"-ot generált csomagonként definiálja.",[455,3574,3575,3576,3579,3580,3583,3584,3587,3588,3590,3591,3593,3594,3597],{},"A validátor feloldása request-időben, ebben a sorrendben: az explicit ",[459,3577,3578],{},"v"," argumentum → a ",[459,3581,3582],{},"server.WithValidator","-ral beállított (a contextből) → ",[459,3585,3586],{},"validate.New()",". A generált kód ezért ",[459,3589,1468],{},"-t ad át: egyetlen ",[459,3592,1642],{}," opció a ",[459,3595,3596],{},"main.go","-ban az egész alkalmazásra érvényes, a generált fájlokhoz nem kell nyúlni.",[547,3599,3601],{"id":3600},"surface-szintű-middleware","Surface-szintű middleware",[455,3603,3604,3605,706,3607,3609,3610,3612,3613,3616],{},"Router-szintű middleware-t a ",[459,3606,1778],{},[459,3608,1781],{}," ad; ami csak egy surface-re vonatkozik (mint a shop admin surface-ének szerepvédelme), azt a surface ",[459,3611,2898],{},"-blokkjában kötöd be, a generátor által az első sorában hagyott ",[459,3614,3615],{},"\u002F\u002F gpsystem:surface-middleware"," anchornál:",[500,3618,3620],{"className":502,"code":3619,"filename":2999,"language":504,"meta":505,"style":505},"func RegisterAdmin(router chi.Router, deps Dependencies) {\n    adminSvc := adminservice.New()\n    adminHandler := adminhttp.New(adminSvc)\n    adminPolicies := adminpolicy.New()\n    router.Route(\"\u002Fadmin\u002Fshop\", func(r chi.Router) {\n        \u002F\u002F gpsystem:surface-middleware\n        r.Use(server.RequireRole(\"admin\"))\n        shopadmingen.HandlerWithOptions(shopadmingen.NewStrictHandlerWithOptions(\n            adminHandler,\n            []shopadmingen.StrictMiddlewareFunc{\n                server.StrictValidator[shopadmingen.StrictHandlerFunc](nil),\n                kitpolicy.Enforcer[shopadmingen.StrictHandlerFunc](adminPolicies, shopadmingen.PermissionByOperation, shopadmingen.PolicyByOperation),\n            },\n            shopadmingen.StrictHTTPServerOptions{\n                RequestErrorHandlerFunc:  httperr.WriteBadRequest,\n                ResponseErrorHandlerFunc: server.WriteError,\n            },\n        ), shopadmingen.ChiServerOptions{\n            BaseRouter:       r,\n            ErrorHandlerFunc: httperr.WriteBadRequest,\n        })\n    })\n}\n",[459,3621,3622,3649,3665,3686,3702,3734,3738,3766,3786,3793,3805,3823,3863,3867,3878,3892,3906,3910,3922,3932,3946,3950,3954],{"__ignoreMap":505},[509,3623,3624,3626,3629,3631,3633,3635,3637,3639,3641,3643,3645,3647],{"class":511,"line":512},[509,3625,1095],{"class":519},[509,3627,3628],{"class":1110}," RegisterAdmin",[509,3630,1331],{"class":519},[509,3632,3013],{"class":1101},[509,3634,1430],{"class":523},[509,3636,595],{"class":519},[509,3638,1435],{"class":523},[509,3640,1345],{"class":519},[509,3642,2397],{"class":1101},[509,3644,3026],{"class":523},[509,3646,1107],{"class":519},[509,3648,583],{"class":519},[509,3650,3651,3654,3656,3659,3661,3663],{"class":511,"line":586},[509,3652,3653],{"class":589},"    adminSvc ",[509,3655,2088],{"class":519},[509,3657,3658],{"class":589}," adminservice",[509,3660,595],{"class":519},[509,3662,1472],{"class":1110},[509,3664,2126],{"class":519},[509,3666,3667,3670,3672,3675,3677,3679,3681,3684],{"class":511,"line":601},[509,3668,3669],{"class":589},"    adminHandler ",[509,3671,2088],{"class":519},[509,3673,3674],{"class":589}," adminhttp",[509,3676,595],{"class":519},[509,3678,1472],{"class":1110},[509,3680,1331],{"class":519},[509,3682,3683],{"class":589},"adminSvc",[509,3685,2062],{"class":519},[509,3687,3688,3691,3693,3696,3698,3700],{"class":511,"line":623},[509,3689,3690],{"class":589},"    adminPolicies ",[509,3692,2088],{"class":519},[509,3694,3695],{"class":589}," adminpolicy",[509,3697,595],{"class":519},[509,3699,1472],{"class":1110},[509,3701,2126],{"class":519},[509,3703,3704,3706,3708,3710,3712,3714,3716,3718,3720,3722,3724,3726,3728,3730,3732],{"class":511,"line":630},[509,3705,3088],{"class":589},[509,3707,595],{"class":519},[509,3709,2898],{"class":1110},[509,3711,1331],{"class":519},[509,3713,2435],{"class":519},[509,3715,3376],{"class":616},[509,3717,2435],{"class":519},[509,3719,1345],{"class":519},[509,3721,1424],{"class":519},[509,3723,1427],{"class":1101},[509,3725,1430],{"class":523},[509,3727,595],{"class":519},[509,3729,1435],{"class":523},[509,3731,1107],{"class":519},[509,3733,583],{"class":519},[509,3735,3736],{"class":511,"line":1975},[509,3737,3122],{"class":626},[509,3739,3740,3742,3744,3746,3748,3750,3752,3755,3757,3759,3762,3764],{"class":511,"line":1980},[509,3741,2425],{"class":589},[509,3743,595],{"class":519},[509,3745,2237],{"class":1110},[509,3747,1331],{"class":519},[509,3749,461],{"class":589},[509,3751,595],{"class":519},[509,3753,3754],{"class":1110},"RequireRole",[509,3756,1331],{"class":519},[509,3758,2435],{"class":519},[509,3760,3761],{"class":616},"admin",[509,3763,2435],{"class":519},[509,3765,2258],{"class":519},[509,3767,3768,3771,3773,3775,3777,3780,3782,3784],{"class":511,"line":1990},[509,3769,3770],{"class":589},"        shopadmingen",[509,3772,595],{"class":519},[509,3774,3132],{"class":1110},[509,3776,1331],{"class":519},[509,3778,3779],{"class":589},"shopadmingen",[509,3781,595],{"class":519},[509,3783,3142],{"class":1110},[509,3785,3145],{"class":519},[509,3787,3788,3791],{"class":511,"line":1995},[509,3789,3790],{"class":589},"            adminHandler",[509,3792,3153],{"class":519},[509,3794,3795,3797,3799,3801,3803],{"class":511,"line":2005},[509,3796,3158],{"class":519},[509,3798,3779],{"class":523},[509,3800,595],{"class":519},[509,3802,3165],{"class":523},[509,3804,2283],{"class":519},[509,3806,3807,3809,3811,3813,3815,3817,3819,3821],{"class":511,"line":2015},[509,3808,3172],{"class":589},[509,3810,595],{"class":519},[509,3812,3177],{"class":1110},[509,3814,2099],{"class":519},[509,3816,3779],{"class":523},[509,3818,595],{"class":519},[509,3820,3186],{"class":523},[509,3822,3189],{"class":519},[509,3824,3825,3827,3829,3831,3833,3835,3837,3839,3841,3844,3846,3849,3851,3853,3855,3857,3859,3861],{"class":511,"line":2025},[509,3826,3199],{"class":589},[509,3828,595],{"class":519},[509,3830,3204],{"class":1110},[509,3832,2099],{"class":519},[509,3834,3779],{"class":523},[509,3836,595],{"class":519},[509,3838,3186],{"class":523},[509,3840,3215],{"class":519},[509,3842,3843],{"class":589},"adminPolicies",[509,3845,1345],{"class":519},[509,3847,3848],{"class":589}," shopadmingen",[509,3850,595],{"class":519},[509,3852,3228],{"class":589},[509,3854,1345],{"class":519},[509,3856,3848],{"class":589},[509,3858,595],{"class":519},[509,3860,3237],{"class":589},[509,3862,2308],{"class":519},[509,3864,3865],{"class":511,"line":2034},[509,3866,3244],{"class":519},[509,3868,3869,3872,3874,3876],{"class":511,"line":2039},[509,3870,3871],{"class":523},"            shopadmingen",[509,3873,595],{"class":519},[509,3875,3254],{"class":523},[509,3877,2283],{"class":519},[509,3879,3880,3882,3884,3886,3888,3890],{"class":511,"line":2049},[509,3881,3261],{"class":589},[509,3883,2292],{"class":519},[509,3885,3266],{"class":589},[509,3887,595],{"class":519},[509,3889,1893],{"class":589},[509,3891,3153],{"class":519},[509,3893,3894,3896,3898,3900,3902,3904],{"class":511,"line":2059},[509,3895,3277],{"class":589},[509,3897,2292],{"class":519},[509,3899,2173],{"class":589},[509,3901,595],{"class":519},[509,3903,1890],{"class":589},[509,3905,3153],{"class":519},[509,3907,3908],{"class":511,"line":2065},[509,3909,3244],{"class":519},[509,3911,3912,3914,3916,3918,3920],{"class":511,"line":2070},[509,3913,3296],{"class":519},[509,3915,3848],{"class":523},[509,3917,595],{"class":519},[509,3919,3303],{"class":523},[509,3921,2283],{"class":519},[509,3923,3924,3926,3928,3930],{"class":511,"line":2082},[509,3925,3310],{"class":589},[509,3927,2292],{"class":519},[509,3929,3315],{"class":589},[509,3931,3153],{"class":519},[509,3933,3934,3936,3938,3940,3942,3944],{"class":511,"line":2111},[509,3935,3322],{"class":589},[509,3937,2292],{"class":519},[509,3939,3327],{"class":589},[509,3941,595],{"class":519},[509,3943,1893],{"class":589},[509,3945,3153],{"class":519},[509,3947,3948],{"class":511,"line":2129},[509,3949,3338],{"class":519},[509,3951,3952],{"class":511,"line":2160},[509,3953,3343],{"class":519},[509,3955,3956],{"class":511,"line":2165},[509,3957,633],{"class":519},[455,3959,2979,3960,3963,3964,3968,3969,1556,3972,3974,3975,3980,3981,3984,3985,3987,3988,3990,3991,3996,3997,4000,4001,4003],{},[459,3961,3962],{},"rbac.Identity"," ilyenkor már a contextben van: az ",[464,3965,3966],{"href":212},[459,3967,1794],{}," bekötötte a ",[459,3970,3971],{},"server.IdentityMiddleware",[459,3973,1797],{}," routerre, így a ",[464,3976,3977],{"href":217},[459,3978,3979],{},"server.RequireRole(\"admin\")"," önmagában véd minden ",[459,3982,3983],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fshop\u002F..."," route-ot (identity nélkül 401, szerep nélkül 403). Az ",[459,3986,1797],{}," surface publikus route-jait nem érinti. ",[459,3989,1794],{}," nélküli projektben elé a kötelező-token ",[464,3992,3993],{"href":212},[459,3994,3995],{},"server.AuthMiddleware"," kerül, az ",[459,3998,3999],{},"auth.Config","-ot a modul ",[459,4002,2280],{},"-én átadva.",[4005,4006,4007,4008,4011,4012,706,4015,4018,4019,4022,4023,4026,4027,4029,4030,4033,4034,4037,4038,706,4041,4044],"tip",{},"A middleware-szintek ökölszabálya: ",[480,4009,4010],{},"processz-szintű"," (rate limit, tenant-feloldás) → ",[459,4013,4014],{},"server.WithMiddleware",[459,4016,4017],{},"server.WithStack","; ",[480,4020,4021],{},"surface-szintű"," (auth, szerep) → ",[459,4024,4025],{},"r.Use"," a surface ",[459,4028,2898],{},"-blokkjának ",[459,4031,4032],{},"gpsystem:surface-middleware"," anchoránál; ",[480,4035,4036],{},"művelet-szintű"," (permission, tulajdonos-ellenőrzés) → ",[459,4039,4040],{},"@permission",[459,4042,4043],{},"@policy"," a specben, az enforcer érvényesíti.",[547,4046,422],{"id":4047},"tesztelés",[455,4049,457,4050,4052,4053,4056],{},[459,4051,1472],{}," a teljesen bekötött routert adja vissza, amit sima ",[459,4054,4055],{},"net\u002Fhttp\u002Fhttptest","-tel tesztelhetsz:",[500,4058,4060],{"className":502,"code":4059,"language":504,"meta":505,"style":505},"r := server.New(server.Config{}, server.WithoutTelemetry())\nr.Post(\"\u002Fthings\", createThing)\n\nsrv := httptest.NewServer(r)\ndefer srv.Close()\nresp, err := http.Post(srv.URL+\"\u002Fthings\", \"application\u002Fjson\", body)\n",[459,4061,4062,4095,4120,4124,4145,4159],{"__ignoreMap":505},[509,4063,4064,4067,4069,4071,4073,4075,4077,4079,4081,4083,4086,4088,4090,4092],{"class":511,"line":512},[509,4065,4066],{"class":589},"r ",[509,4068,2088],{"class":519},[509,4070,2173],{"class":589},[509,4072,595],{"class":519},[509,4074,1472],{"class":1110},[509,4076,1331],{"class":519},[509,4078,461],{"class":523},[509,4080,595],{"class":519},[509,4082,550],{"class":523},[509,4084,4085],{"class":519},"{},",[509,4087,2173],{"class":589},[509,4089,595],{"class":519},[509,4091,1577],{"class":1110},[509,4093,4094],{"class":519},"())\n",[509,4096,4097,4099,4101,4104,4106,4108,4111,4113,4115,4118],{"class":511,"line":586},[509,4098,1427],{"class":589},[509,4100,595],{"class":519},[509,4102,4103],{"class":1110},"Post",[509,4105,1331],{"class":519},[509,4107,2435],{"class":519},[509,4109,4110],{"class":616},"\u002Fthings",[509,4112,2435],{"class":519},[509,4114,1345],{"class":519},[509,4116,4117],{"class":589}," createThing",[509,4119,2062],{"class":519},[509,4121,4122],{"class":511,"line":601},[509,4123,1090],{"emptyLinePlaceholder":1089},[509,4125,4126,4129,4131,4134,4136,4139,4141,4143],{"class":511,"line":623},[509,4127,4128],{"class":589},"srv ",[509,4130,2088],{"class":519},[509,4132,4133],{"class":589}," httptest",[509,4135,595],{"class":519},[509,4137,4138],{"class":1110},"NewServer",[509,4140,1331],{"class":519},[509,4142,1427],{"class":589},[509,4144,2062],{"class":519},[509,4146,4147,4150,4153,4155,4157],{"class":511,"line":630},[509,4148,4149],{"class":515},"defer",[509,4151,4152],{"class":589}," srv",[509,4154,595],{"class":519},[509,4156,2514],{"class":1110},[509,4158,2126],{"class":519},[509,4160,4161,4164,4166,4168,4170,4172,4174,4176,4178,4181,4183,4186,4189,4191,4193,4195,4197,4199,4202,4204,4206,4209],{"class":511,"line":1975},[509,4162,4163],{"class":589},"resp",[509,4165,1345],{"class":519},[509,4167,2545],{"class":589},[509,4169,2088],{"class":519},[509,4171,3475],{"class":589},[509,4173,595],{"class":519},[509,4175,4103],{"class":1110},[509,4177,1331],{"class":519},[509,4179,4180],{"class":589},"srv",[509,4182,595],{"class":519},[509,4184,4185],{"class":589},"URL",[509,4187,4188],{"class":519},"+",[509,4190,2435],{"class":519},[509,4192,4110],{"class":616},[509,4194,2435],{"class":519},[509,4196,1345],{"class":519},[509,4198,520],{"class":519},[509,4200,4201],{"class":616},"application\u002Fjson",[509,4203,2435],{"class":519},[509,4205,1345],{"class":519},[509,4207,4208],{"class":589}," body",[509,4210,2062],{"class":519},[455,4212,4213],{},"A panic-recoverer, a 404\u002F405 problem-kezelők és a body limit ilyenkor is aktívak, tehát a teszt pontosan azt a problem+json választ látja, amit a kliens fog.",[547,4215,4217],{"id":4216},"használt-patternek","Használt patternek",[1024,4219,4220,4235],{},[1027,4221,4222,1098,4225,706,4228,4231,4232,595],{},[480,4223,4224],{},"Context-injektált validator",[459,4226,4227],{},"injectValidator",[459,4229,4230],{},"validatorFromContext",", unexported context-kulccsal): ",[464,4233,200],{"href":4234},"\u002Fhu\u002Fconcepts\u002Fdesign-patterns#context-injekt%C3%A1lt-f%C3%BCgg%C5%91s%C3%A9g",[1027,4236,4237,1098,4240,4243,4244,4246,4247,595],{},[480,4238,4239],{},"Generikus middleware-adapter",[459,4241,4242],{},"StrictValidator[H ~func(...)]",", illeszkedik minden generált ",[459,4245,3186],{},"-hoz): ",[464,4248,200],{"href":4249},"\u002Fhu\u002Fconcepts\u002Fdesign-patterns#generikus-middleware-adapter",[547,4251,4253],{"id":4252},"kapcsolódó-oldalak","Kapcsolódó oldalak",[1024,4255,4256,4268,4273,4278],{},[1027,4257,4258,4260,4261,4264,4265,4267],{},[464,4259,130],{"href":131},": a közös ",[459,4262,4263],{},"app.Run"," váz, amire a ",[459,4266,544],{}," épül.",[1027,4269,4270,4272],{},[464,4271,318],{"href":319},": a teljes hiba-mapping tábla.",[1027,4274,4275,4277],{},[464,4276,323],{"href":324},": saját validációs tagek.",[1027,4279,4280,4282],{},[464,4281,221],{"href":222},": a fent használt enforcer.",[4284,4285,4286],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":505,"searchDepth":586,"depth":586,"links":4288},[4289,4295,4296,4299,4302,4305,4306,4307,4308],{"id":549,"depth":586,"text":550,"children":4290},[4291,4292,4293,4294],{"id":1018,"depth":601,"text":1019},{"id":1054,"depth":601,"text":1055},{"id":1146,"depth":601,"text":979},{"id":1183,"depth":601,"text":1184},{"id":1228,"depth":586,"text":1229},{"id":1315,"depth":586,"text":1316,"children":4297},[4298],{"id":1869,"depth":601,"text":1870},{"id":1921,"depth":586,"text":1922,"children":4300},[4301],{"id":2616,"depth":601,"text":2617},{"id":2975,"depth":586,"text":2976,"children":4303},[4304],{"id":3438,"depth":601,"text":3439},{"id":3600,"depth":586,"text":3601},{"id":4047,"depth":586,"text":422},{"id":4216,"depth":586,"text":4217},{"id":4252,"depth":586,"text":4253},"A chi-alapú HTTP-chassis: Config (timeoutok, CORS, body limit), a közös életciklus, és hogy mit köt be a server.Run.","md",null,{},{"icon":138},{"title":135,"description":4309},"sC1D6nKAwp1gtY8g1xwHOyO59W_FguzXCP5U76IjKP0",[4317,4319],{"title":130,"path":131,"stem":132,"description":4318,"icon":133,"children":-1},"Az app csomag: signal-vezérelt graceful shutdown, amin minden gpsystem bináris ül.",{"title":140,"path":141,"stem":142,"description":4320,"icon":114,"children":-1},"A háttérmunka-chassis, asynq szerver, outbox relay és schedule runner egyetlen binárisban, közös graceful shutdownnal.",1787346795317]