[{"data":1,"prerenderedAt":354},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fmain\u002Farchitecture":3},{"id":4,"title":5,"body":6,"description":341,"extension":342,"group":343,"meta":344,"navigation":345,"order":346,"path":347,"section":348,"seo":349,"source":350,"stem":351,"version":352,"__hash__":353},"docs\u002Fdocs\u002Fmain\u002Farchitecture.md","Application architecture",{"type":7,"value":8,"toc":333},"minimark",[9,14,29,33,40,195,203,207,210,274,277,281,300,304,312,316,329],[10,11,13],"h2",{"id":12},"start-small","Start small",[15,16,17,18,22,23,28],"p",{},"Your first application can fit in one ",[19,20,21],"code",{},"main.go",". As it grows, organize your own business modules; you do not need to edit the Gonex package. The ",[24,25,27],"a",{"href":26},"\u002Fdocs\u002Fmain\u002Fproject-structure\u002F","project structure guide"," shows concrete file responsibilities.",[10,30,32],{"id":31},"compose-modules-explicitly","Compose modules explicitly",[15,34,35,36,39],{},"A module implements ",[19,37,38],{},"Register(*app.Registrar) error",". The executable constructs the application and registers its modules:",[41,42,47],"pre",{"className":43,"code":44,"language":45,"meta":46,"style":46},"language-go shiki shiki-themes light-plus light-plus dark-plus","a, err := gonex.New(config.Config{})\nif err != nil { return err }\nif err = a.Register(users.Module{}, catalog.Module{}); err != nil { return err }\nreturn a.Run(ctx)\n","go","",[19,48,49,92,120,174],{"__ignoreMap":46},[50,51,54,57,61,64,67,70,73,77,80,84,86,89],"span",{"class":52,"line":53},"line",1,[50,55,24],{"class":56},"sswaR",[50,58,60],{"class":59},"s_Yst",", ",[50,62,63],{"class":56},"err",[50,65,66],{"class":59}," := ",[50,68,69],{"class":56},"gonex",[50,71,72],{"class":59},".",[50,74,76],{"class":75},"swoLU","New",[50,78,79],{"class":59},"(",[50,81,83],{"class":82},"sopvc","config",[50,85,72],{"class":59},[50,87,88],{"class":82},"Config",[50,90,91],{"class":59},"{})\n",[50,93,95,99,102,105,109,112,115,117],{"class":52,"line":94},2,[50,96,98],{"class":97},"smUd-","if",[50,100,101],{"class":56}," err",[50,103,104],{"class":59}," != ",[50,106,108],{"class":107},"stxUP","nil",[50,110,111],{"class":59}," { ",[50,113,114],{"class":97},"return",[50,116,101],{"class":56},[50,118,119],{"class":59}," }\n",[50,121,123,125,127,130,132,134,137,139,142,144,147,150,153,155,157,160,162,164,166,168,170,172],{"class":52,"line":122},3,[50,124,98],{"class":97},[50,126,101],{"class":56},[50,128,129],{"class":59}," = ",[50,131,24],{"class":56},[50,133,72],{"class":59},[50,135,136],{"class":75},"Register",[50,138,79],{"class":59},[50,140,141],{"class":82},"users",[50,143,72],{"class":59},[50,145,146],{"class":82},"Module",[50,148,149],{"class":59},"{}, ",[50,151,152],{"class":82},"catalog",[50,154,72],{"class":59},[50,156,146],{"class":82},[50,158,159],{"class":59},"{}); ",[50,161,63],{"class":56},[50,163,104],{"class":59},[50,165,108],{"class":107},[50,167,111],{"class":59},[50,169,114],{"class":97},[50,171,101],{"class":56},[50,173,119],{"class":59},[50,175,177,179,182,184,187,189,192],{"class":52,"line":176},4,[50,178,114],{"class":97},[50,180,181],{"class":56}," a",[50,183,72],{"class":59},[50,185,186],{"class":75},"Run",[50,188,79],{"class":59},[50,190,191],{"class":56},"ctx",[50,193,194],{"class":59},")\n",[15,196,197,198,202],{},"This excerpt assumes your application defines the two module types and has an existing context. See the ",[24,199,201],{"href":200},"\u002Fdocs\u002Fmain\u002Fquick-start\u002F","complete quick-start program"," for a runnable single-module example.",[10,204,206],{"id":205},"keep-business-rules-in-your-service","Keep business rules in your service",[15,208,209],{},"Your HTTP handler translates requests into service calls. Your service accepts ordinary Go values and depends on small local interfaces. GORM and gRPC implementations sit behind those interfaces when needed.",[211,212,213,226],"table",{},[214,215,216],"thead",{},[217,218,219,223],"tr",{},[220,221,222],"th",{},"Layer in your application",[220,224,225],{},"Owns",[227,228,229,238,250,258,266],"tbody",{},[217,230,231,235],{},[232,233,234],"td",{},"Service",[232,236,237],{},"Business rules and consumer-owned dependency interfaces",[217,239,240,243],{},[232,241,242],{},"HTTP adapter",[232,244,245,246,249],{},"Request\u002Fresponse ",[19,247,248],{},"schemas.go",", validation and status mapping",[217,251,252,255],{},[232,253,254],{},"Database adapter",[232,256,257],{},"GORM models, queries and persistence mapping",[217,259,260,263],{},[232,261,262],{},"gRPC adapter",[232,264,265],{},"Versioned Protobuf mapping and remote calls",[217,267,268,271],{},[232,269,270],{},"Executable\u002Fmodule registration",[232,272,273],{},"Construction, configuration and resource composition",[15,275,276],{},"Use a modular monolith first when that fits your application. Independent services and gRPC are optional; there is no requirement to adopt them for an HTTP API.",[10,278,280],{"id":279},"let-the-application-own-resources","Let the application own resources",[15,282,283,284,287,288,291,292,287,296,72],{},"Managed resources expose ",[19,285,286],{},"Start(context.Context) error"," and ",[19,289,290],{},"Close(context.Context) error",". Register dependencies before consumers and honor cancellation. Gonex starts them in registration order and closes them in reverse during shutdown. See ",[24,293,295],{"href":294},"\u002Fdocs\u002Fmain\u002Fmodules\u002F","modules and lifecycle",[24,297,299],{"href":298},"\u002Fdocs\u002Fmain\u002Foperations\u002F","operations",[10,301,303],{"id":302},"framework-internals-are-a-separate-path","Framework internals are a separate path",[15,305,306,307,311],{},"If your goal is to change how Gonex itself registers routes, generates contracts or scaffolds code, use ",[24,308,310],{"href":309},"\u002Fdocs\u002Fmain\u002Fcontribute\u002Farchitecture\u002F","Framework internals",". This main documentation describes how to build your own application with the public API.",[10,313,315],{"id":314},"local-microservices-workflow","Local microservices workflow",[15,317,318,319,323,324,328],{},"Follow ",[24,320,322],{"href":321},"\u002Fdocs\u002Fmain\u002Fmicroservices-quickstart\u002F","First microservice call"," for explicit client profiles and wiring, dev\u002Fdoctor and independently published contracts. Existing generated paths and TLS defaults are retained. ",[24,325,327],{"href":326},"\u002Fdocs\u002Fmain\u002Fmicroservices-compatibility\u002F","Compatibility"," explains skeleton\u002Fexample\u002Fraw profiles, version coexistence and generation checks.",[330,331,332],"style",{},"html pre.shiki code .sswaR, html code.shiki .sswaR{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#9CDCFE}html pre.shiki code .s_Yst, html code.shiki .s_Yst{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#D4D4D4}html pre.shiki code .swoLU, html code.shiki .swoLU{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .sopvc, html code.shiki .sopvc{--shiki-light:#267F99;--shiki-default:#267F99;--shiki-dark:#4EC9B0}html pre.shiki code .smUd-, html code.shiki .smUd-{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#C586C0}html pre.shiki code .stxUP, html code.shiki .stxUP{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#569CD6}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":46,"searchDepth":94,"depth":94,"links":334},[335,336,337,338,339,340],{"id":12,"depth":94,"text":13},{"id":31,"depth":94,"text":32},{"id":205,"depth":94,"text":206},{"id":279,"depth":94,"text":280},{"id":302,"depth":94,"text":303},{"id":314,"depth":94,"text":315},"Structure a Gonex application around plain Go business services, explicit modules and optional HTTP, database and gRPC adapters.","md","APPLICATION DESIGN",{},true,50,"\u002Fdocs\u002Fmain\u002Farchitecture","build",{"title":5,"description":341},null,"docs\u002Fmain\u002Farchitecture","main","XpRZJrjDU4qNg_wNKdfAXPwK2MdmJQrM3aHux_0hQnA",1792521640184]