[{"data":1,"prerenderedAt":3453},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fmain\u002Fbuilding-api":3},{"id":4,"title":5,"body":6,"description":3442,"extension":3443,"group":3444,"meta":3445,"navigation":170,"order":591,"path":3446,"section":3447,"seo":3448,"source":3449,"stem":3450,"version":3451,"__hash__":3452},"docs\u002Fdocs\u002Fmain\u002Fbuilding-api.md","Build a REST API",{"type":7,"value":8,"toc":3431},"minimark",[9,14,18,109,126,140,144,151,1149,1153,1160,1349,1353,1359,1774,1778,1784,2085,2091,2150,2154,2164,2759,2763,2769,3153,3157,3192,3199,3210,3248,3254,3295,3321,3395,3402,3406,3427],[10,11,13],"h2",{"id":12},"create-a-separate-api-project","Create a separate API project",[15,16,17],"p",{},"Use Go 1.27.2. Start in an empty parent directory, not inside the quick-start shop:",[19,20,25],"pre",{"className":21,"code":22,"language":23,"meta":24,"style":24},"language-sh shiki shiki-themes light-plus light-plus dark-plus","go install github.com\u002Famkargar\u002Fgonex\u002Fcmd\u002Fgonex@3ca54b46cb42\ngonex new api --module example.com\u002Fshop\ncd api\ngo mod tidy\ngo tool gonex create module users --transport none\n","sh","",[26,27,28,44,63,72,83],"code",{"__ignoreMap":24},[29,30,33,37,41],"span",{"class":31,"line":32},"line",1,[29,34,36],{"class":35},"swoLU","go",[29,38,40],{"class":39},"sFD8J"," install",[29,42,43],{"class":39}," github.com\u002Famkargar\u002Fgonex\u002Fcmd\u002Fgonex@3ca54b46cb42\n",[29,45,47,50,53,56,60],{"class":31,"line":46},2,[29,48,49],{"class":35},"gonex",[29,51,52],{"class":39}," new",[29,54,55],{"class":39}," api",[29,57,59],{"class":58},"stxUP"," --module",[29,61,62],{"class":39}," example.com\u002Fshop\n",[29,64,66,69],{"class":31,"line":65},3,[29,67,68],{"class":35},"cd",[29,70,71],{"class":39}," api\n",[29,73,75,77,80],{"class":31,"line":74},4,[29,76,36],{"class":35},[29,78,79],{"class":39}," mod",[29,81,82],{"class":39}," tidy\n",[29,84,86,88,91,94,97,100,103,106],{"class":31,"line":85},5,[29,87,36],{"class":35},[29,89,90],{"class":39}," tool",[29,92,93],{"class":39}," gonex",[29,95,96],{"class":39}," create",[29,98,99],{"class":39}," module",[29,101,102],{"class":39}," users",[29,104,105],{"class":58}," --transport",[29,107,108],{"class":39}," none\n",[15,110,111,112,115,116,119,120,125],{},"We start with a generated business module and add its handwritten HTTP adapter below. ",[26,113,114],{},"--transport none"," avoids a starter ",[26,117,118],{},"\u002Fusers"," route while we define the complete resource contract. The normal HTTP scaffold is covered in ",[121,122,124],"a",{"href":123},"\u002Fdocs\u002Fmain\u002Fquick-start\u002F","Quick start",".",[15,127,128,129,132,133,139],{},"Keep the generated main.go, config\u002Fconfig.go, modules\u002Fregistry_gen.go and .gonex.json. Replace the generated users service\u002Fmodule files with the following code, create ",[26,130,131],{},"modules\u002Fusers\u002Fhttp\u002F",", and replace the starter service test with your own tests. The ",[121,134,138],{"href":135,"rel":136},"https:\u002F\u002Fgithub.com\u002Famkargar\u002FGoNex-website\u002Ftree\u002Fmain\u002Fexamples\u002Fapi",[137],"nofollow","complete tested source"," includes these exact files and API tests. You can copy the files into your generated app; cloning either repository is unnecessary.",[10,141,143],{"id":142},"define-the-business-service","Define the business service",[15,145,146,147,150],{},"Replace ",[26,148,149],{},"modules\u002Fusers\u002Fservice.go",". This example stores users in memory with concurrent access protection. Data is lost on restart; add a repository for persistence.",[19,152,155],{"className":153,"code":154,"language":36,"meta":24,"style":24},"language-go shiki shiki-themes light-plus light-plus dark-plus","package users\n\nimport (\n    \"context\"\n    \"strconv\"\n    \"sync\"\n\n    apperrors \"github.com\u002Famkargar\u002Fgonex\u002Ferrors\"\n    \"github.com\u002Famkargar\u002Fgonex\u002Fobservability\"\n)\n\ntype User struct{ ID, Name, Email string }\ntype Service struct {\n    mu    sync.RWMutex\n    users []User\n}\n\nfunc NewService() *Service { return &Service{} }\n\nfunc (s *Service) Create(ctx context.Context, name, email string) (User, error) {\n    if err := ctx.Err(); err != nil {\n        return User{}, err\n    }\n    s.mu.Lock()\n    for _, u := range s.users {\n        if u.Email == email {\n            s.mu.Unlock()\n            return User{}, apperrors.New(apperrors.Conflict, \"email already exists\")\n        }\n    }\n    user := User{ID: strconv.Itoa(len(s.users) + 1), Name: name, Email: email}\n    s.users = append(s.users, user)\n    s.mu.Unlock()\n    observability.Logger(ctx, nil).InfoContext(ctx, \"user created\", \"module\", \"users\", \"user_id\", user.ID)\n    return user, nil\n}\nfunc (s *Service) List(ctx context.Context) ([]User, error) {\n    if err := ctx.Err(); err != nil {\n        return nil, err\n    }\n    s.mu.RLock()\n    defer s.mu.RUnlock()\n    return append([]User(nil), s.users...), nil\n}\nfunc (s *Service) Get(ctx context.Context, id string) (User, error) {\n    if err := ctx.Err(); err != nil {\n        return User{}, err\n    }\n    s.mu.RLock()\n    defer s.mu.RUnlock()\n    for _, u := range s.users {\n        if u.ID == id {\n            return u, nil\n        }\n    }\n    return User{}, apperrors.New(apperrors.NotFound, \"user not found\")\n}\n",[26,156,157,166,172,182,187,192,198,203,213,219,225,230,265,278,292,304,310,315,344,349,411,444,458,464,483,512,532,549,583,589,594,660,690,705,764,778,783,822,847,859,864,880,899,929,934,979,1004,1015,1020,1035,1052,1075,1092,1103,1108,1113,1144],{"__ignoreMap":24},[29,158,159,162],{"class":31,"line":32},[29,160,161],{"class":58},"package",[29,163,165],{"class":164},"sopvc"," users\n",[29,167,168],{"class":31,"line":46},[29,169,171],{"emptyLinePlaceholder":170},true,"\n",[29,173,174,178],{"class":31,"line":65},[29,175,177],{"class":176},"smUd-","import",[29,179,181],{"class":180},"s_Yst"," (\n",[29,183,184],{"class":31,"line":74},[29,185,186],{"class":39},"    \"context\"\n",[29,188,189],{"class":31,"line":85},[29,190,191],{"class":39},"    \"strconv\"\n",[29,193,195],{"class":31,"line":194},6,[29,196,197],{"class":39},"    \"sync\"\n",[29,199,201],{"class":31,"line":200},7,[29,202,171],{"emptyLinePlaceholder":170},[29,204,206,210],{"class":31,"line":205},8,[29,207,209],{"class":208},"sswaR","    apperrors",[29,211,212],{"class":39}," \"github.com\u002Famkargar\u002Fgonex\u002Ferrors\"\n",[29,214,216],{"class":31,"line":215},9,[29,217,218],{"class":39},"    \"github.com\u002Famkargar\u002Fgonex\u002Fobservability\"\n",[29,220,222],{"class":31,"line":221},10,[29,223,224],{"class":180},")\n",[29,226,228],{"class":31,"line":227},11,[29,229,171],{"emptyLinePlaceholder":170},[29,231,233,236,239,242,245,248,251,254,256,259,262],{"class":31,"line":232},12,[29,234,235],{"class":58},"type",[29,237,238],{"class":164}," User",[29,240,241],{"class":58}," struct",[29,243,244],{"class":180},"{ ",[29,246,247],{"class":208},"ID",[29,249,250],{"class":180},", ",[29,252,253],{"class":208},"Name",[29,255,250],{"class":180},[29,257,258],{"class":208},"Email",[29,260,261],{"class":164}," string",[29,263,264],{"class":180}," }\n",[29,266,268,270,273,275],{"class":31,"line":267},13,[29,269,235],{"class":58},[29,271,272],{"class":164}," Service",[29,274,241],{"class":58},[29,276,277],{"class":180}," {\n",[29,279,281,284,287,289],{"class":31,"line":280},14,[29,282,283],{"class":208},"    mu",[29,285,286],{"class":164},"    sync",[29,288,125],{"class":180},[29,290,291],{"class":164},"RWMutex\n",[29,293,295,298,301],{"class":31,"line":294},15,[29,296,297],{"class":208},"    users",[29,299,300],{"class":180}," []",[29,302,303],{"class":164},"User\n",[29,305,307],{"class":31,"line":306},16,[29,308,309],{"class":180},"}\n",[29,311,313],{"class":31,"line":312},17,[29,314,171],{"emptyLinePlaceholder":170},[29,316,318,321,324,327,330,333,336,339,341],{"class":31,"line":317},18,[29,319,320],{"class":58},"func",[29,322,323],{"class":35}," NewService",[29,325,326],{"class":180},"() *",[29,328,329],{"class":164},"Service",[29,331,332],{"class":180}," { ",[29,334,335],{"class":176},"return",[29,337,338],{"class":180}," &",[29,340,329],{"class":164},[29,342,343],{"class":180},"{} }\n",[29,345,347],{"class":31,"line":346},19,[29,348,171],{"emptyLinePlaceholder":170},[29,350,352,354,357,360,363,365,368,371,374,377,380,382,385,387,390,392,395,397,400,403,405,408],{"class":31,"line":351},20,[29,353,320],{"class":58},[29,355,356],{"class":180}," (",[29,358,359],{"class":208},"s ",[29,361,362],{"class":180},"*",[29,364,329],{"class":164},[29,366,367],{"class":180},") ",[29,369,370],{"class":35},"Create",[29,372,373],{"class":180},"(",[29,375,376],{"class":208},"ctx",[29,378,379],{"class":164}," context",[29,381,125],{"class":180},[29,383,384],{"class":164},"Context",[29,386,250],{"class":180},[29,388,389],{"class":208},"name",[29,391,250],{"class":180},[29,393,394],{"class":208},"email",[29,396,261],{"class":164},[29,398,399],{"class":180},") (",[29,401,402],{"class":164},"User",[29,404,250],{"class":180},[29,406,407],{"class":164},"error",[29,409,410],{"class":180},") {\n",[29,412,414,417,420,423,425,427,430,433,436,439,442],{"class":31,"line":413},21,[29,415,416],{"class":176},"    if",[29,418,419],{"class":208}," err",[29,421,422],{"class":180}," := ",[29,424,376],{"class":208},[29,426,125],{"class":180},[29,428,429],{"class":35},"Err",[29,431,432],{"class":180},"(); ",[29,434,435],{"class":208},"err",[29,437,438],{"class":180}," != ",[29,440,441],{"class":58},"nil",[29,443,277],{"class":180},[29,445,447,450,452,455],{"class":31,"line":446},22,[29,448,449],{"class":176},"        return",[29,451,238],{"class":164},[29,453,454],{"class":180},"{}, ",[29,456,457],{"class":208},"err\n",[29,459,461],{"class":31,"line":460},23,[29,462,463],{"class":180},"    }\n",[29,465,467,470,472,475,477,480],{"class":31,"line":466},24,[29,468,469],{"class":208},"    s",[29,471,125],{"class":180},[29,473,474],{"class":208},"mu",[29,476,125],{"class":180},[29,478,479],{"class":35},"Lock",[29,481,482],{"class":180},"()\n",[29,484,486,489,492,494,497,499,502,505,507,510],{"class":31,"line":485},25,[29,487,488],{"class":176},"    for",[29,490,491],{"class":208}," _",[29,493,250],{"class":180},[29,495,496],{"class":208},"u",[29,498,422],{"class":180},[29,500,501],{"class":176},"range",[29,503,504],{"class":208}," s",[29,506,125],{"class":180},[29,508,509],{"class":208},"users",[29,511,277],{"class":180},[29,513,515,518,521,523,525,528,530],{"class":31,"line":514},26,[29,516,517],{"class":176},"        if",[29,519,520],{"class":208}," u",[29,522,125],{"class":180},[29,524,258],{"class":208},[29,526,527],{"class":180}," == ",[29,529,394],{"class":208},[29,531,277],{"class":180},[29,533,535,538,540,542,544,547],{"class":31,"line":534},27,[29,536,537],{"class":208},"            s",[29,539,125],{"class":180},[29,541,474],{"class":208},[29,543,125],{"class":180},[29,545,546],{"class":35},"Unlock",[29,548,482],{"class":180},[29,550,552,555,557,559,562,564,567,569,571,573,576,578,581],{"class":31,"line":551},28,[29,553,554],{"class":176},"            return",[29,556,238],{"class":164},[29,558,454],{"class":180},[29,560,561],{"class":208},"apperrors",[29,563,125],{"class":180},[29,565,566],{"class":35},"New",[29,568,373],{"class":180},[29,570,561],{"class":208},[29,572,125],{"class":180},[29,574,575],{"class":208},"Conflict",[29,577,250],{"class":180},[29,579,580],{"class":39},"\"email already exists\"",[29,582,224],{"class":180},[29,584,586],{"class":31,"line":585},29,[29,587,588],{"class":180},"        }\n",[29,590,592],{"class":31,"line":591},30,[29,593,463],{"class":180},[29,595,597,600,602,604,607,609,612,615,617,620,622,625,627,630,632,634,637,641,644,646,648,650,652,654,656,658],{"class":31,"line":596},31,[29,598,599],{"class":208},"    user",[29,601,422],{"class":180},[29,603,402],{"class":164},[29,605,606],{"class":180},"{",[29,608,247],{"class":208},[29,610,611],{"class":180},": ",[29,613,614],{"class":208},"strconv",[29,616,125],{"class":180},[29,618,619],{"class":35},"Itoa",[29,621,373],{"class":180},[29,623,624],{"class":35},"len",[29,626,373],{"class":180},[29,628,629],{"class":208},"s",[29,631,125],{"class":180},[29,633,509],{"class":208},[29,635,636],{"class":180},") + ",[29,638,640],{"class":639},"s-S-M","1",[29,642,643],{"class":180},"), ",[29,645,253],{"class":208},[29,647,611],{"class":180},[29,649,389],{"class":208},[29,651,250],{"class":180},[29,653,258],{"class":208},[29,655,611],{"class":180},[29,657,394],{"class":208},[29,659,309],{"class":180},[29,661,663,665,667,669,672,675,677,679,681,683,685,688],{"class":31,"line":662},32,[29,664,469],{"class":208},[29,666,125],{"class":180},[29,668,509],{"class":208},[29,670,671],{"class":180}," = ",[29,673,674],{"class":35},"append",[29,676,373],{"class":180},[29,678,629],{"class":208},[29,680,125],{"class":180},[29,682,509],{"class":208},[29,684,250],{"class":180},[29,686,687],{"class":208},"user",[29,689,224],{"class":180},[29,691,693,695,697,699,701,703],{"class":31,"line":692},33,[29,694,469],{"class":208},[29,696,125],{"class":180},[29,698,474],{"class":208},[29,700,125],{"class":180},[29,702,546],{"class":35},[29,704,482],{"class":180},[29,706,708,711,713,716,718,720,722,724,727,730,732,734,736,739,741,744,746,749,751,754,756,758,760,762],{"class":31,"line":707},34,[29,709,710],{"class":208},"    observability",[29,712,125],{"class":180},[29,714,715],{"class":35},"Logger",[29,717,373],{"class":180},[29,719,376],{"class":208},[29,721,250],{"class":180},[29,723,441],{"class":58},[29,725,726],{"class":180},").",[29,728,729],{"class":35},"InfoContext",[29,731,373],{"class":180},[29,733,376],{"class":208},[29,735,250],{"class":180},[29,737,738],{"class":39},"\"user created\"",[29,740,250],{"class":180},[29,742,743],{"class":39},"\"module\"",[29,745,250],{"class":180},[29,747,748],{"class":39},"\"users\"",[29,750,250],{"class":180},[29,752,753],{"class":39},"\"user_id\"",[29,755,250],{"class":180},[29,757,687],{"class":208},[29,759,125],{"class":180},[29,761,247],{"class":208},[29,763,224],{"class":180},[29,765,767,770,773,775],{"class":31,"line":766},35,[29,768,769],{"class":176},"    return",[29,771,772],{"class":208}," user",[29,774,250],{"class":180},[29,776,777],{"class":58},"nil\n",[29,779,781],{"class":31,"line":780},36,[29,782,309],{"class":180},[29,784,786,788,790,792,794,796,798,801,803,805,807,809,811,814,816,818,820],{"class":31,"line":785},37,[29,787,320],{"class":58},[29,789,356],{"class":180},[29,791,359],{"class":208},[29,793,362],{"class":180},[29,795,329],{"class":164},[29,797,367],{"class":180},[29,799,800],{"class":35},"List",[29,802,373],{"class":180},[29,804,376],{"class":208},[29,806,379],{"class":164},[29,808,125],{"class":180},[29,810,384],{"class":164},[29,812,813],{"class":180},") ([]",[29,815,402],{"class":164},[29,817,250],{"class":180},[29,819,407],{"class":164},[29,821,410],{"class":180},[29,823,825,827,829,831,833,835,837,839,841,843,845],{"class":31,"line":824},38,[29,826,416],{"class":176},[29,828,419],{"class":208},[29,830,422],{"class":180},[29,832,376],{"class":208},[29,834,125],{"class":180},[29,836,429],{"class":35},[29,838,432],{"class":180},[29,840,435],{"class":208},[29,842,438],{"class":180},[29,844,441],{"class":58},[29,846,277],{"class":180},[29,848,850,852,855,857],{"class":31,"line":849},39,[29,851,449],{"class":176},[29,853,854],{"class":58}," nil",[29,856,250],{"class":180},[29,858,457],{"class":208},[29,860,862],{"class":31,"line":861},40,[29,863,463],{"class":180},[29,865,867,869,871,873,875,878],{"class":31,"line":866},41,[29,868,469],{"class":208},[29,870,125],{"class":180},[29,872,474],{"class":208},[29,874,125],{"class":180},[29,876,877],{"class":35},"RLock",[29,879,482],{"class":180},[29,881,883,886,888,890,892,894,897],{"class":31,"line":882},42,[29,884,885],{"class":176},"    defer",[29,887,504],{"class":208},[29,889,125],{"class":180},[29,891,474],{"class":208},[29,893,125],{"class":180},[29,895,896],{"class":35},"RUnlock",[29,898,482],{"class":180},[29,900,902,904,907,910,912,914,916,918,920,922,924,927],{"class":31,"line":901},43,[29,903,769],{"class":176},[29,905,906],{"class":35}," append",[29,908,909],{"class":180},"([]",[29,911,402],{"class":35},[29,913,373],{"class":180},[29,915,441],{"class":58},[29,917,643],{"class":180},[29,919,629],{"class":208},[29,921,125],{"class":180},[29,923,509],{"class":208},[29,925,926],{"class":180},"...), ",[29,928,777],{"class":58},[29,930,932],{"class":31,"line":931},44,[29,933,309],{"class":180},[29,935,937,939,941,943,945,947,949,952,954,956,958,960,962,964,967,969,971,973,975,977],{"class":31,"line":936},45,[29,938,320],{"class":58},[29,940,356],{"class":180},[29,942,359],{"class":208},[29,944,362],{"class":180},[29,946,329],{"class":164},[29,948,367],{"class":180},[29,950,951],{"class":35},"Get",[29,953,373],{"class":180},[29,955,376],{"class":208},[29,957,379],{"class":164},[29,959,125],{"class":180},[29,961,384],{"class":164},[29,963,250],{"class":180},[29,965,966],{"class":208},"id",[29,968,261],{"class":164},[29,970,399],{"class":180},[29,972,402],{"class":164},[29,974,250],{"class":180},[29,976,407],{"class":164},[29,978,410],{"class":180},[29,980,982,984,986,988,990,992,994,996,998,1000,1002],{"class":31,"line":981},46,[29,983,416],{"class":176},[29,985,419],{"class":208},[29,987,422],{"class":180},[29,989,376],{"class":208},[29,991,125],{"class":180},[29,993,429],{"class":35},[29,995,432],{"class":180},[29,997,435],{"class":208},[29,999,438],{"class":180},[29,1001,441],{"class":58},[29,1003,277],{"class":180},[29,1005,1007,1009,1011,1013],{"class":31,"line":1006},47,[29,1008,449],{"class":176},[29,1010,238],{"class":164},[29,1012,454],{"class":180},[29,1014,457],{"class":208},[29,1016,1018],{"class":31,"line":1017},48,[29,1019,463],{"class":180},[29,1021,1023,1025,1027,1029,1031,1033],{"class":31,"line":1022},49,[29,1024,469],{"class":208},[29,1026,125],{"class":180},[29,1028,474],{"class":208},[29,1030,125],{"class":180},[29,1032,877],{"class":35},[29,1034,482],{"class":180},[29,1036,1038,1040,1042,1044,1046,1048,1050],{"class":31,"line":1037},50,[29,1039,885],{"class":176},[29,1041,504],{"class":208},[29,1043,125],{"class":180},[29,1045,474],{"class":208},[29,1047,125],{"class":180},[29,1049,896],{"class":35},[29,1051,482],{"class":180},[29,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073],{"class":31,"line":1054},51,[29,1056,488],{"class":176},[29,1058,491],{"class":208},[29,1060,250],{"class":180},[29,1062,496],{"class":208},[29,1064,422],{"class":180},[29,1066,501],{"class":176},[29,1068,504],{"class":208},[29,1070,125],{"class":180},[29,1072,509],{"class":208},[29,1074,277],{"class":180},[29,1076,1078,1080,1082,1084,1086,1088,1090],{"class":31,"line":1077},52,[29,1079,517],{"class":176},[29,1081,520],{"class":208},[29,1083,125],{"class":180},[29,1085,247],{"class":208},[29,1087,527],{"class":180},[29,1089,966],{"class":208},[29,1091,277],{"class":180},[29,1093,1095,1097,1099,1101],{"class":31,"line":1094},53,[29,1096,554],{"class":176},[29,1098,520],{"class":208},[29,1100,250],{"class":180},[29,1102,777],{"class":58},[29,1104,1106],{"class":31,"line":1105},54,[29,1107,588],{"class":180},[29,1109,1111],{"class":31,"line":1110},55,[29,1112,463],{"class":180},[29,1114,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1137,1139,1142],{"class":31,"line":1115},56,[29,1117,769],{"class":176},[29,1119,238],{"class":164},[29,1121,454],{"class":180},[29,1123,561],{"class":208},[29,1125,125],{"class":180},[29,1127,566],{"class":35},[29,1129,373],{"class":180},[29,1131,561],{"class":208},[29,1133,125],{"class":180},[29,1135,1136],{"class":208},"NotFound",[29,1138,250],{"class":180},[29,1140,1141],{"class":39},"\"user not found\"",[29,1143,224],{"class":180},[29,1145,1147],{"class":31,"line":1146},57,[29,1148,309],{"class":180},[10,1150,1152],{"id":1151},"define-request-and-response-schemas","Define request and response schemas",[15,1154,1155,1156,1159],{},"Create ",[26,1157,1158],{},"modules\u002Fusers\u002Fhttp\u002Fschemas.go",". The body wrapper declares JSON binding; validation rejects invalid names\u002Femails before the service is called.",[19,1161,1163],{"className":153,"code":1162,"language":36,"meta":24,"style":24},"package usershttp\n\ntype CreateBody struct {\n    Name  string `json:\"name\" validate:\"required,min=2,max=80\"`\n    Email string `json:\"email\" validate:\"required,email,max=254\"`\n}\ntype CreateRequest struct {\n    Body CreateBody `body:\"true\"`\n}\ntype GetRequest struct {\n    ID string `path:\"id\" validate:\"required\"`\n}\ntype UserResponse struct {\n    ID    string `json:\"id\"`\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\ntype ListResponse struct {\n    Items []UserResponse `json:\"items\"`\n}\n\ntype ListRequest struct{}\n",[26,1164,1165,1172,1176,1187,1198,1208,1212,1223,1233,1237,1248,1258,1262,1273,1283,1292,1301,1305,1316,1329,1333,1337],{"__ignoreMap":24},[29,1166,1167,1169],{"class":31,"line":32},[29,1168,161],{"class":58},[29,1170,1171],{"class":164}," usershttp\n",[29,1173,1174],{"class":31,"line":46},[29,1175,171],{"emptyLinePlaceholder":170},[29,1177,1178,1180,1183,1185],{"class":31,"line":65},[29,1179,235],{"class":58},[29,1181,1182],{"class":164}," CreateBody",[29,1184,241],{"class":58},[29,1186,277],{"class":180},[29,1188,1189,1192,1195],{"class":31,"line":74},[29,1190,1191],{"class":208},"    Name",[29,1193,1194],{"class":164},"  string",[29,1196,1197],{"class":39}," `json:\"name\" validate:\"required,min=2,max=80\"`\n",[29,1199,1200,1203,1205],{"class":31,"line":85},[29,1201,1202],{"class":208},"    Email",[29,1204,261],{"class":164},[29,1206,1207],{"class":39}," `json:\"email\" validate:\"required,email,max=254\"`\n",[29,1209,1210],{"class":31,"line":194},[29,1211,309],{"class":180},[29,1213,1214,1216,1219,1221],{"class":31,"line":200},[29,1215,235],{"class":58},[29,1217,1218],{"class":164}," CreateRequest",[29,1220,241],{"class":58},[29,1222,277],{"class":180},[29,1224,1225,1228,1230],{"class":31,"line":205},[29,1226,1227],{"class":208},"    Body",[29,1229,1182],{"class":164},[29,1231,1232],{"class":39}," `body:\"true\"`\n",[29,1234,1235],{"class":31,"line":215},[29,1236,309],{"class":180},[29,1238,1239,1241,1244,1246],{"class":31,"line":221},[29,1240,235],{"class":58},[29,1242,1243],{"class":164}," GetRequest",[29,1245,241],{"class":58},[29,1247,277],{"class":180},[29,1249,1250,1253,1255],{"class":31,"line":227},[29,1251,1252],{"class":208},"    ID",[29,1254,261],{"class":164},[29,1256,1257],{"class":39}," `path:\"id\" validate:\"required\"`\n",[29,1259,1260],{"class":31,"line":232},[29,1261,309],{"class":180},[29,1263,1264,1266,1269,1271],{"class":31,"line":267},[29,1265,235],{"class":58},[29,1267,1268],{"class":164}," UserResponse",[29,1270,241],{"class":58},[29,1272,277],{"class":180},[29,1274,1275,1277,1280],{"class":31,"line":280},[29,1276,1252],{"class":208},[29,1278,1279],{"class":164},"    string",[29,1281,1282],{"class":39}," `json:\"id\"`\n",[29,1284,1285,1287,1289],{"class":31,"line":294},[29,1286,1191],{"class":208},[29,1288,1194],{"class":164},[29,1290,1291],{"class":39}," `json:\"name\"`\n",[29,1293,1294,1296,1298],{"class":31,"line":306},[29,1295,1202],{"class":208},[29,1297,261],{"class":164},[29,1299,1300],{"class":39}," `json:\"email\"`\n",[29,1302,1303],{"class":31,"line":312},[29,1304,309],{"class":180},[29,1306,1307,1309,1312,1314],{"class":31,"line":317},[29,1308,235],{"class":58},[29,1310,1311],{"class":164}," ListResponse",[29,1313,241],{"class":58},[29,1315,277],{"class":180},[29,1317,1318,1321,1323,1326],{"class":31,"line":346},[29,1319,1320],{"class":208},"    Items",[29,1322,300],{"class":180},[29,1324,1325],{"class":164},"UserResponse",[29,1327,1328],{"class":39}," `json:\"items\"`\n",[29,1330,1331],{"class":31,"line":351},[29,1332,309],{"class":180},[29,1334,1335],{"class":31,"line":413},[29,1336,171],{"emptyLinePlaceholder":170},[29,1338,1339,1341,1344,1346],{"class":31,"line":446},[29,1340,235],{"class":58},[29,1342,1343],{"class":164}," ListRequest",[29,1345,241],{"class":58},[29,1347,1348],{"class":180},"{}\n",[10,1350,1352],{"id":1351},"map-requests-to-actions","Map requests to actions",[15,1354,1155,1355,1358],{},[26,1356,1357],{},"modules\u002Fusers\u002Fhttp\u002Fhandlers.go",". The HTTP adapter accepts explicit actions and does not import database models.",[19,1360,1362],{"className":153,"code":1361,"language":36,"meta":24,"style":24},"package usershttp\n\nimport \"context\"\n\ntype Actions struct {\n    Create func(context.Context, string, string) (UserResponse, error)\n    List   func(context.Context) ([]UserResponse, error)\n    Get    func(context.Context, string) (UserResponse, error)\n}\ntype Handler struct{ Actions Actions }\n\nfunc (h Handler) Create(ctx context.Context, in CreateRequest) (UserResponse, error) {\n    return h.Actions.Create(ctx, in.Body.Name, in.Body.Email)\n}\nfunc (h Handler) List(ctx context.Context, _ ListRequest) (ListResponse, error) {\n    items, err := h.Actions.List(ctx)\n    return ListResponse{Items: items}, err\n}\nfunc (h Handler) Get(ctx context.Context, in GetRequest) (UserResponse, error) {\n    return h.Actions.Get(ctx, in.ID)\n}\n",[26,1363,1364,1370,1374,1381,1385,1396,1432,1458,1488,1492,1510,1514,1557,1603,1607,1649,1677,1698,1702,1742,1770],{"__ignoreMap":24},[29,1365,1366,1368],{"class":31,"line":32},[29,1367,161],{"class":58},[29,1369,1171],{"class":164},[29,1371,1372],{"class":31,"line":46},[29,1373,171],{"emptyLinePlaceholder":170},[29,1375,1376,1378],{"class":31,"line":65},[29,1377,177],{"class":176},[29,1379,1380],{"class":39}," \"context\"\n",[29,1382,1383],{"class":31,"line":74},[29,1384,171],{"emptyLinePlaceholder":170},[29,1386,1387,1389,1392,1394],{"class":31,"line":85},[29,1388,235],{"class":58},[29,1390,1391],{"class":164}," Actions",[29,1393,241],{"class":58},[29,1395,277],{"class":180},[29,1397,1398,1401,1404,1406,1409,1411,1413,1415,1418,1420,1422,1424,1426,1428,1430],{"class":31,"line":194},[29,1399,1400],{"class":208},"    Create",[29,1402,1403],{"class":58}," func",[29,1405,373],{"class":180},[29,1407,1408],{"class":164},"context",[29,1410,125],{"class":180},[29,1412,384],{"class":164},[29,1414,250],{"class":180},[29,1416,1417],{"class":164},"string",[29,1419,250],{"class":180},[29,1421,1417],{"class":164},[29,1423,399],{"class":180},[29,1425,1325],{"class":164},[29,1427,250],{"class":180},[29,1429,407],{"class":164},[29,1431,224],{"class":180},[29,1433,1434,1437,1440,1442,1444,1446,1448,1450,1452,1454,1456],{"class":31,"line":200},[29,1435,1436],{"class":208},"    List",[29,1438,1439],{"class":58},"   func",[29,1441,373],{"class":180},[29,1443,1408],{"class":164},[29,1445,125],{"class":180},[29,1447,384],{"class":164},[29,1449,813],{"class":180},[29,1451,1325],{"class":164},[29,1453,250],{"class":180},[29,1455,407],{"class":164},[29,1457,224],{"class":180},[29,1459,1460,1463,1466,1468,1470,1472,1474,1476,1478,1480,1482,1484,1486],{"class":31,"line":205},[29,1461,1462],{"class":208},"    Get",[29,1464,1465],{"class":58},"    func",[29,1467,373],{"class":180},[29,1469,1408],{"class":164},[29,1471,125],{"class":180},[29,1473,384],{"class":164},[29,1475,250],{"class":180},[29,1477,1417],{"class":164},[29,1479,399],{"class":180},[29,1481,1325],{"class":164},[29,1483,250],{"class":180},[29,1485,407],{"class":164},[29,1487,224],{"class":180},[29,1489,1490],{"class":31,"line":215},[29,1491,309],{"class":180},[29,1493,1494,1496,1499,1501,1503,1506,1508],{"class":31,"line":221},[29,1495,235],{"class":58},[29,1497,1498],{"class":164}," Handler",[29,1500,241],{"class":58},[29,1502,244],{"class":180},[29,1504,1505],{"class":208},"Actions",[29,1507,1391],{"class":164},[29,1509,264],{"class":180},[29,1511,1512],{"class":31,"line":227},[29,1513,171],{"emptyLinePlaceholder":170},[29,1515,1516,1518,1520,1523,1526,1528,1530,1532,1534,1536,1538,1540,1542,1545,1547,1549,1551,1553,1555],{"class":31,"line":232},[29,1517,320],{"class":58},[29,1519,356],{"class":180},[29,1521,1522],{"class":208},"h ",[29,1524,1525],{"class":164},"Handler",[29,1527,367],{"class":180},[29,1529,370],{"class":35},[29,1531,373],{"class":180},[29,1533,376],{"class":208},[29,1535,379],{"class":164},[29,1537,125],{"class":180},[29,1539,384],{"class":164},[29,1541,250],{"class":180},[29,1543,1544],{"class":208},"in",[29,1546,1218],{"class":164},[29,1548,399],{"class":180},[29,1550,1325],{"class":164},[29,1552,250],{"class":180},[29,1554,407],{"class":164},[29,1556,410],{"class":180},[29,1558,1559,1561,1564,1566,1568,1570,1572,1574,1576,1578,1580,1582,1585,1587,1589,1591,1593,1595,1597,1599,1601],{"class":31,"line":267},[29,1560,769],{"class":176},[29,1562,1563],{"class":208}," h",[29,1565,125],{"class":180},[29,1567,1505],{"class":208},[29,1569,125],{"class":180},[29,1571,370],{"class":35},[29,1573,373],{"class":180},[29,1575,376],{"class":208},[29,1577,250],{"class":180},[29,1579,1544],{"class":208},[29,1581,125],{"class":180},[29,1583,1584],{"class":208},"Body",[29,1586,125],{"class":180},[29,1588,253],{"class":208},[29,1590,250],{"class":180},[29,1592,1544],{"class":208},[29,1594,125],{"class":180},[29,1596,1584],{"class":208},[29,1598,125],{"class":180},[29,1600,258],{"class":208},[29,1602,224],{"class":180},[29,1604,1605],{"class":31,"line":280},[29,1606,309],{"class":180},[29,1608,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1636,1638,1640,1643,1645,1647],{"class":31,"line":294},[29,1610,320],{"class":58},[29,1612,356],{"class":180},[29,1614,1522],{"class":208},[29,1616,1525],{"class":164},[29,1618,367],{"class":180},[29,1620,800],{"class":35},[29,1622,373],{"class":180},[29,1624,376],{"class":208},[29,1626,379],{"class":164},[29,1628,125],{"class":180},[29,1630,384],{"class":164},[29,1632,250],{"class":180},[29,1634,1635],{"class":208},"_",[29,1637,1343],{"class":164},[29,1639,399],{"class":180},[29,1641,1642],{"class":164},"ListResponse",[29,1644,250],{"class":180},[29,1646,407],{"class":164},[29,1648,410],{"class":180},[29,1650,1651,1654,1656,1658,1660,1663,1665,1667,1669,1671,1673,1675],{"class":31,"line":306},[29,1652,1653],{"class":208},"    items",[29,1655,250],{"class":180},[29,1657,435],{"class":208},[29,1659,422],{"class":180},[29,1661,1662],{"class":208},"h",[29,1664,125],{"class":180},[29,1666,1505],{"class":208},[29,1668,125],{"class":180},[29,1670,800],{"class":35},[29,1672,373],{"class":180},[29,1674,376],{"class":208},[29,1676,224],{"class":180},[29,1678,1679,1681,1683,1685,1688,1690,1693,1696],{"class":31,"line":312},[29,1680,769],{"class":176},[29,1682,1311],{"class":164},[29,1684,606],{"class":180},[29,1686,1687],{"class":208},"Items",[29,1689,611],{"class":180},[29,1691,1692],{"class":208},"items",[29,1694,1695],{"class":180},"}, ",[29,1697,457],{"class":208},[29,1699,1700],{"class":31,"line":317},[29,1701,309],{"class":180},[29,1703,1704,1706,1708,1710,1712,1714,1716,1718,1720,1722,1724,1726,1728,1730,1732,1734,1736,1738,1740],{"class":31,"line":346},[29,1705,320],{"class":58},[29,1707,356],{"class":180},[29,1709,1522],{"class":208},[29,1711,1525],{"class":164},[29,1713,367],{"class":180},[29,1715,951],{"class":35},[29,1717,373],{"class":180},[29,1719,376],{"class":208},[29,1721,379],{"class":164},[29,1723,125],{"class":180},[29,1725,384],{"class":164},[29,1727,250],{"class":180},[29,1729,1544],{"class":208},[29,1731,1243],{"class":164},[29,1733,399],{"class":180},[29,1735,1325],{"class":164},[29,1737,250],{"class":180},[29,1739,407],{"class":164},[29,1741,410],{"class":180},[29,1743,1744,1746,1748,1750,1752,1754,1756,1758,1760,1762,1764,1766,1768],{"class":31,"line":351},[29,1745,769],{"class":176},[29,1747,1563],{"class":208},[29,1749,125],{"class":180},[29,1751,1505],{"class":208},[29,1753,125],{"class":180},[29,1755,951],{"class":35},[29,1757,373],{"class":180},[29,1759,376],{"class":208},[29,1761,250],{"class":180},[29,1763,1544],{"class":208},[29,1765,125],{"class":180},[29,1767,247],{"class":208},[29,1769,224],{"class":180},[29,1771,1772],{"class":31,"line":413},[29,1773,309],{"class":180},[10,1775,1777],{"id":1776},"register-typed-endpoints","Register typed endpoints",[15,1779,1155,1780,1783],{},[26,1781,1782],{},"modules\u002Fusers\u002Fhttp\u002Froutes.go",". Use concise typed declarations. Handler input\u002Foutput types are inferred; Post defaults to 201 and Get to 200. Declare each operation name and domain error so OpenAPI matches runtime behavior.",[19,1785,1787],{"className":153,"code":1786,"language":36,"meta":24,"style":24},"package usershttp\n\nimport transport \"github.com\u002Famkargar\u002Fgonex\u002Fhttp\"\n\nfunc Register(r transport.EndpointRegistrar, actions Actions) error {\n    h := Handler{Actions: actions}\n    return transport.Routes(r,\n        transport.Post(\"\u002Fapi\u002Fusers\", h.Create).\n            Name(\"createUser\").\n            Summary(createSummary).\n            Tags(\"users\").\n            Errors(409),\n        transport.Get(\"\u002Fapi\u002Fusers\", h.List).\n            Name(\"listUsers\").\n            Summary(listSummary).\n            Tags(\"users\"),\n        transport.Get(\"\u002Fapi\u002Fusers\u002F:id\", h.Get).\n            Name(\"getUser\").\n            Summary(getSummary).\n            Tags(\"users\").\n            Errors(404),\n    )\n}\n",[26,1788,1789,1795,1799,1809,1813,1845,1864,1882,1908,1920,1932,1943,1956,1978,1989,2000,2010,2033,2044,2055,2065,2076,2081],{"__ignoreMap":24},[29,1790,1791,1793],{"class":31,"line":32},[29,1792,161],{"class":58},[29,1794,1171],{"class":164},[29,1796,1797],{"class":31,"line":46},[29,1798,171],{"emptyLinePlaceholder":170},[29,1800,1801,1803,1806],{"class":31,"line":65},[29,1802,177],{"class":176},[29,1804,1805],{"class":208}," transport",[29,1807,1808],{"class":39}," \"github.com\u002Famkargar\u002Fgonex\u002Fhttp\"\n",[29,1810,1811],{"class":31,"line":74},[29,1812,171],{"emptyLinePlaceholder":170},[29,1814,1815,1817,1820,1822,1825,1827,1829,1832,1834,1837,1839,1841,1843],{"class":31,"line":85},[29,1816,320],{"class":58},[29,1818,1819],{"class":35}," Register",[29,1821,373],{"class":180},[29,1823,1824],{"class":208},"r",[29,1826,1805],{"class":164},[29,1828,125],{"class":180},[29,1830,1831],{"class":164},"EndpointRegistrar",[29,1833,250],{"class":180},[29,1835,1836],{"class":208},"actions",[29,1838,1391],{"class":164},[29,1840,367],{"class":180},[29,1842,407],{"class":164},[29,1844,277],{"class":180},[29,1846,1847,1850,1852,1854,1856,1858,1860,1862],{"class":31,"line":194},[29,1848,1849],{"class":208},"    h",[29,1851,422],{"class":180},[29,1853,1525],{"class":164},[29,1855,606],{"class":180},[29,1857,1505],{"class":208},[29,1859,611],{"class":180},[29,1861,1836],{"class":208},[29,1863,309],{"class":180},[29,1865,1866,1868,1870,1872,1875,1877,1879],{"class":31,"line":200},[29,1867,769],{"class":176},[29,1869,1805],{"class":208},[29,1871,125],{"class":180},[29,1873,1874],{"class":35},"Routes",[29,1876,373],{"class":180},[29,1878,1824],{"class":208},[29,1880,1881],{"class":180},",\n",[29,1883,1884,1887,1889,1892,1894,1897,1899,1901,1903,1905],{"class":31,"line":205},[29,1885,1886],{"class":208},"        transport",[29,1888,125],{"class":180},[29,1890,1891],{"class":35},"Post",[29,1893,373],{"class":180},[29,1895,1896],{"class":39},"\"\u002Fapi\u002Fusers\"",[29,1898,250],{"class":180},[29,1900,1662],{"class":208},[29,1902,125],{"class":180},[29,1904,370],{"class":208},[29,1906,1907],{"class":180},").\n",[29,1909,1910,1913,1915,1918],{"class":31,"line":215},[29,1911,1912],{"class":35},"            Name",[29,1914,373],{"class":180},[29,1916,1917],{"class":39},"\"createUser\"",[29,1919,1907],{"class":180},[29,1921,1922,1925,1927,1930],{"class":31,"line":221},[29,1923,1924],{"class":35},"            Summary",[29,1926,373],{"class":180},[29,1928,1929],{"class":208},"createSummary",[29,1931,1907],{"class":180},[29,1933,1934,1937,1939,1941],{"class":31,"line":227},[29,1935,1936],{"class":35},"            Tags",[29,1938,373],{"class":180},[29,1940,748],{"class":39},[29,1942,1907],{"class":180},[29,1944,1945,1948,1950,1953],{"class":31,"line":232},[29,1946,1947],{"class":35},"            Errors",[29,1949,373],{"class":180},[29,1951,1952],{"class":639},"409",[29,1954,1955],{"class":180},"),\n",[29,1957,1958,1960,1962,1964,1966,1968,1970,1972,1974,1976],{"class":31,"line":267},[29,1959,1886],{"class":208},[29,1961,125],{"class":180},[29,1963,951],{"class":35},[29,1965,373],{"class":180},[29,1967,1896],{"class":39},[29,1969,250],{"class":180},[29,1971,1662],{"class":208},[29,1973,125],{"class":180},[29,1975,800],{"class":208},[29,1977,1907],{"class":180},[29,1979,1980,1982,1984,1987],{"class":31,"line":280},[29,1981,1912],{"class":35},[29,1983,373],{"class":180},[29,1985,1986],{"class":39},"\"listUsers\"",[29,1988,1907],{"class":180},[29,1990,1991,1993,1995,1998],{"class":31,"line":294},[29,1992,1924],{"class":35},[29,1994,373],{"class":180},[29,1996,1997],{"class":208},"listSummary",[29,1999,1907],{"class":180},[29,2001,2002,2004,2006,2008],{"class":31,"line":306},[29,2003,1936],{"class":35},[29,2005,373],{"class":180},[29,2007,748],{"class":39},[29,2009,1955],{"class":180},[29,2011,2012,2014,2016,2018,2020,2023,2025,2027,2029,2031],{"class":31,"line":312},[29,2013,1886],{"class":208},[29,2015,125],{"class":180},[29,2017,951],{"class":35},[29,2019,373],{"class":180},[29,2021,2022],{"class":39},"\"\u002Fapi\u002Fusers\u002F:id\"",[29,2024,250],{"class":180},[29,2026,1662],{"class":208},[29,2028,125],{"class":180},[29,2030,951],{"class":208},[29,2032,1907],{"class":180},[29,2034,2035,2037,2039,2042],{"class":31,"line":317},[29,2036,1912],{"class":35},[29,2038,373],{"class":180},[29,2040,2041],{"class":39},"\"getUser\"",[29,2043,1907],{"class":180},[29,2045,2046,2048,2050,2053],{"class":31,"line":346},[29,2047,1924],{"class":35},[29,2049,373],{"class":180},[29,2051,2052],{"class":208},"getSummary",[29,2054,1907],{"class":180},[29,2056,2057,2059,2061,2063],{"class":31,"line":351},[29,2058,1936],{"class":35},[29,2060,373],{"class":180},[29,2062,748],{"class":39},[29,2064,1907],{"class":180},[29,2066,2067,2069,2071,2074],{"class":31,"line":413},[29,2068,1947],{"class":35},[29,2070,373],{"class":180},[29,2072,2073],{"class":639},"404",[29,2075,1955],{"class":180},[29,2077,2078],{"class":31,"line":446},[29,2079,2080],{"class":180},"    )\n",[29,2082,2083],{"class":31,"line":460},[29,2084,309],{"class":180},[15,2086,1155,2087,2090],{},[26,2088,2089],{},"modules\u002Fusers\u002Fhttp\u002Fopenapi.go",":",[19,2092,2094],{"className":153,"code":2093,"language":36,"meta":24,"style":24},"package usershttp\n\nconst (\n    createSummary = \"Create a user\"\n    listSummary   = \"List users\"\n    getSummary    = \"Get a user\"\n)\n",[26,2095,2096,2102,2106,2113,2124,2135,2146],{"__ignoreMap":24},[29,2097,2098,2100],{"class":31,"line":32},[29,2099,161],{"class":58},[29,2101,1171],{"class":164},[29,2103,2104],{"class":31,"line":46},[29,2105,171],{"emptyLinePlaceholder":170},[29,2107,2108,2111],{"class":31,"line":65},[29,2109,2110],{"class":58},"const",[29,2112,181],{"class":180},[29,2114,2115,2119,2121],{"class":31,"line":74},[29,2116,2118],{"class":2117},"syj1l","    createSummary",[29,2120,671],{"class":180},[29,2122,2123],{"class":39},"\"Create a user\"\n",[29,2125,2126,2129,2132],{"class":31,"line":85},[29,2127,2128],{"class":2117},"    listSummary",[29,2130,2131],{"class":180},"   = ",[29,2133,2134],{"class":39},"\"List users\"\n",[29,2136,2137,2140,2143],{"class":31,"line":194},[29,2138,2139],{"class":2117},"    getSummary",[29,2141,2142],{"class":180},"    = ",[29,2144,2145],{"class":39},"\"Get a user\"\n",[29,2147,2148],{"class":31,"line":200},[29,2149,224],{"class":180},[10,2151,2153],{"id":2152},"wire-the-module","Wire the module",[15,2155,146,2156,2159,2160,2163],{},[26,2157,2158],{},"modules\u002Fusers\u002Fmodule.go",". Explicit mapping keeps service values separate from HTTP DTOs. The existing generated module registry already registers ",[26,2161,2162],{},"users.Module{}","; do not edit it.",[19,2165,2167],{"className":153,"code":2166,"language":36,"meta":24,"style":24},"package users\n\nimport (\n    \"context\"\n    usershttp \"example.com\u002Fshop\u002Fmodules\u002Fusers\u002Fhttp\"\n    \"github.com\u002Famkargar\u002Fgonex\u002Fapp\"\n)\n\ntype Module struct{ Service *Service }\n\nfunc (m Module) Register(r *app.Registrar) error {\n    service := m.Service\n    if service == nil {\n        service = NewService()\n    }\n    response := func(u User) usershttp.UserResponse {\n        return usershttp.UserResponse{ID: u.ID, Name: u.Name, Email: u.Email}\n    }\n    return usershttp.Register(r, usershttp.Actions{\n        Create: func(ctx context.Context, name, email string) (usershttp.UserResponse, error) {\n            u, err := service.Create(ctx, name, email)\n            return response(u), err\n        },\n        Get: func(ctx context.Context, id string) (usershttp.UserResponse, error) {\n            u, err := service.Get(ctx, id)\n            return response(u), err\n        },\n        List: func(ctx context.Context) ([]usershttp.UserResponse, error) {\n            users, err := service.List(ctx)\n            items := make([]usershttp.UserResponse, 0, len(users))\n            for _, u := range users {\n                items = append(items, response(u))\n            }\n            return items, err\n        },\n    })\n}\n",[26,2168,2169,2175,2179,2185,2189,2197,2202,2206,2210,2230,2234,2271,2286,2299,2311,2315,2341,2390,2394,2419,2462,2494,2509,2514,2553,2579,2593,2597,2630,2653,2687,2706,2730,2735,2746,2750,2755],{"__ignoreMap":24},[29,2170,2171,2173],{"class":31,"line":32},[29,2172,161],{"class":58},[29,2174,165],{"class":164},[29,2176,2177],{"class":31,"line":46},[29,2178,171],{"emptyLinePlaceholder":170},[29,2180,2181,2183],{"class":31,"line":65},[29,2182,177],{"class":176},[29,2184,181],{"class":180},[29,2186,2187],{"class":31,"line":74},[29,2188,186],{"class":39},[29,2190,2191,2194],{"class":31,"line":85},[29,2192,2193],{"class":208},"    usershttp",[29,2195,2196],{"class":39}," \"example.com\u002Fshop\u002Fmodules\u002Fusers\u002Fhttp\"\n",[29,2198,2199],{"class":31,"line":194},[29,2200,2201],{"class":39},"    \"github.com\u002Famkargar\u002Fgonex\u002Fapp\"\n",[29,2203,2204],{"class":31,"line":200},[29,2205,224],{"class":180},[29,2207,2208],{"class":31,"line":205},[29,2209,171],{"emptyLinePlaceholder":170},[29,2211,2212,2214,2217,2219,2221,2223,2226,2228],{"class":31,"line":215},[29,2213,235],{"class":58},[29,2215,2216],{"class":164}," Module",[29,2218,241],{"class":58},[29,2220,244],{"class":180},[29,2222,329],{"class":208},[29,2224,2225],{"class":180}," *",[29,2227,329],{"class":164},[29,2229,264],{"class":180},[29,2231,2232],{"class":31,"line":221},[29,2233,171],{"emptyLinePlaceholder":170},[29,2235,2236,2238,2240,2243,2246,2248,2251,2253,2255,2257,2260,2262,2265,2267,2269],{"class":31,"line":227},[29,2237,320],{"class":58},[29,2239,356],{"class":180},[29,2241,2242],{"class":208},"m ",[29,2244,2245],{"class":164},"Module",[29,2247,367],{"class":180},[29,2249,2250],{"class":35},"Register",[29,2252,373],{"class":180},[29,2254,1824],{"class":208},[29,2256,2225],{"class":180},[29,2258,2259],{"class":164},"app",[29,2261,125],{"class":180},[29,2263,2264],{"class":164},"Registrar",[29,2266,367],{"class":180},[29,2268,407],{"class":164},[29,2270,277],{"class":180},[29,2272,2273,2276,2278,2281,2283],{"class":31,"line":232},[29,2274,2275],{"class":208},"    service",[29,2277,422],{"class":180},[29,2279,2280],{"class":208},"m",[29,2282,125],{"class":180},[29,2284,2285],{"class":208},"Service\n",[29,2287,2288,2290,2293,2295,2297],{"class":31,"line":267},[29,2289,416],{"class":176},[29,2291,2292],{"class":208}," service",[29,2294,527],{"class":180},[29,2296,441],{"class":58},[29,2298,277],{"class":180},[29,2300,2301,2304,2306,2309],{"class":31,"line":280},[29,2302,2303],{"class":208},"        service",[29,2305,671],{"class":180},[29,2307,2308],{"class":35},"NewService",[29,2310,482],{"class":180},[29,2312,2313],{"class":31,"line":294},[29,2314,463],{"class":180},[29,2316,2317,2320,2322,2324,2326,2328,2330,2332,2335,2337,2339],{"class":31,"line":306},[29,2318,2319],{"class":208},"    response",[29,2321,422],{"class":180},[29,2323,320],{"class":58},[29,2325,373],{"class":180},[29,2327,496],{"class":208},[29,2329,238],{"class":164},[29,2331,367],{"class":180},[29,2333,2334],{"class":164},"usershttp",[29,2336,125],{"class":180},[29,2338,1325],{"class":164},[29,2340,277],{"class":180},[29,2342,2343,2345,2348,2350,2352,2354,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374,2376,2378,2380,2382,2384,2386,2388],{"class":31,"line":312},[29,2344,449],{"class":176},[29,2346,2347],{"class":164}," usershttp",[29,2349,125],{"class":180},[29,2351,1325],{"class":164},[29,2353,606],{"class":180},[29,2355,247],{"class":208},[29,2357,611],{"class":180},[29,2359,496],{"class":208},[29,2361,125],{"class":180},[29,2363,247],{"class":208},[29,2365,250],{"class":180},[29,2367,253],{"class":208},[29,2369,611],{"class":180},[29,2371,496],{"class":208},[29,2373,125],{"class":180},[29,2375,253],{"class":208},[29,2377,250],{"class":180},[29,2379,258],{"class":208},[29,2381,611],{"class":180},[29,2383,496],{"class":208},[29,2385,125],{"class":180},[29,2387,258],{"class":208},[29,2389,309],{"class":180},[29,2391,2392],{"class":31,"line":317},[29,2393,463],{"class":180},[29,2395,2396,2398,2400,2402,2404,2406,2408,2410,2412,2414,2416],{"class":31,"line":346},[29,2397,769],{"class":176},[29,2399,2347],{"class":208},[29,2401,125],{"class":180},[29,2403,2250],{"class":35},[29,2405,373],{"class":180},[29,2407,1824],{"class":208},[29,2409,250],{"class":180},[29,2411,2334],{"class":164},[29,2413,125],{"class":180},[29,2415,1505],{"class":164},[29,2417,2418],{"class":180},"{\n",[29,2420,2421,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446,2448,2450,2452,2454,2456,2458,2460],{"class":31,"line":351},[29,2422,2423],{"class":208},"        Create",[29,2425,611],{"class":180},[29,2427,320],{"class":58},[29,2429,373],{"class":180},[29,2431,376],{"class":208},[29,2433,379],{"class":164},[29,2435,125],{"class":180},[29,2437,384],{"class":164},[29,2439,250],{"class":180},[29,2441,389],{"class":208},[29,2443,250],{"class":180},[29,2445,394],{"class":208},[29,2447,261],{"class":164},[29,2449,399],{"class":180},[29,2451,2334],{"class":164},[29,2453,125],{"class":180},[29,2455,1325],{"class":164},[29,2457,250],{"class":180},[29,2459,407],{"class":164},[29,2461,410],{"class":180},[29,2463,2464,2467,2469,2471,2473,2476,2478,2480,2482,2484,2486,2488,2490,2492],{"class":31,"line":413},[29,2465,2466],{"class":208},"            u",[29,2468,250],{"class":180},[29,2470,435],{"class":208},[29,2472,422],{"class":180},[29,2474,2475],{"class":208},"service",[29,2477,125],{"class":180},[29,2479,370],{"class":35},[29,2481,373],{"class":180},[29,2483,376],{"class":208},[29,2485,250],{"class":180},[29,2487,389],{"class":208},[29,2489,250],{"class":180},[29,2491,394],{"class":208},[29,2493,224],{"class":180},[29,2495,2496,2498,2501,2503,2505,2507],{"class":31,"line":446},[29,2497,554],{"class":176},[29,2499,2500],{"class":35}," response",[29,2502,373],{"class":180},[29,2504,496],{"class":208},[29,2506,643],{"class":180},[29,2508,457],{"class":208},[29,2510,2511],{"class":31,"line":460},[29,2512,2513],{"class":180},"        },\n",[29,2515,2516,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551],{"class":31,"line":466},[29,2517,2518],{"class":208},"        Get",[29,2520,611],{"class":180},[29,2522,320],{"class":58},[29,2524,373],{"class":180},[29,2526,376],{"class":208},[29,2528,379],{"class":164},[29,2530,125],{"class":180},[29,2532,384],{"class":164},[29,2534,250],{"class":180},[29,2536,966],{"class":208},[29,2538,261],{"class":164},[29,2540,399],{"class":180},[29,2542,2334],{"class":164},[29,2544,125],{"class":180},[29,2546,1325],{"class":164},[29,2548,250],{"class":180},[29,2550,407],{"class":164},[29,2552,410],{"class":180},[29,2554,2555,2557,2559,2561,2563,2565,2567,2569,2571,2573,2575,2577],{"class":31,"line":485},[29,2556,2466],{"class":208},[29,2558,250],{"class":180},[29,2560,435],{"class":208},[29,2562,422],{"class":180},[29,2564,2475],{"class":208},[29,2566,125],{"class":180},[29,2568,951],{"class":35},[29,2570,373],{"class":180},[29,2572,376],{"class":208},[29,2574,250],{"class":180},[29,2576,966],{"class":208},[29,2578,224],{"class":180},[29,2580,2581,2583,2585,2587,2589,2591],{"class":31,"line":514},[29,2582,554],{"class":176},[29,2584,2500],{"class":35},[29,2586,373],{"class":180},[29,2588,496],{"class":208},[29,2590,643],{"class":180},[29,2592,457],{"class":208},[29,2594,2595],{"class":31,"line":534},[29,2596,2513],{"class":180},[29,2598,2599,2602,2604,2606,2608,2610,2612,2614,2616,2618,2620,2622,2624,2626,2628],{"class":31,"line":551},[29,2600,2601],{"class":208},"        List",[29,2603,611],{"class":180},[29,2605,320],{"class":58},[29,2607,373],{"class":180},[29,2609,376],{"class":208},[29,2611,379],{"class":164},[29,2613,125],{"class":180},[29,2615,384],{"class":164},[29,2617,813],{"class":180},[29,2619,2334],{"class":164},[29,2621,125],{"class":180},[29,2623,1325],{"class":164},[29,2625,250],{"class":180},[29,2627,407],{"class":164},[29,2629,410],{"class":180},[29,2631,2632,2635,2637,2639,2641,2643,2645,2647,2649,2651],{"class":31,"line":585},[29,2633,2634],{"class":208},"            users",[29,2636,250],{"class":180},[29,2638,435],{"class":208},[29,2640,422],{"class":180},[29,2642,2475],{"class":208},[29,2644,125],{"class":180},[29,2646,800],{"class":35},[29,2648,373],{"class":180},[29,2650,376],{"class":208},[29,2652,224],{"class":180},[29,2654,2655,2658,2660,2663,2665,2667,2669,2671,2673,2676,2678,2680,2682,2684],{"class":31,"line":591},[29,2656,2657],{"class":208},"            items",[29,2659,422],{"class":180},[29,2661,2662],{"class":35},"make",[29,2664,909],{"class":180},[29,2666,2334],{"class":164},[29,2668,125],{"class":180},[29,2670,1325],{"class":164},[29,2672,250],{"class":180},[29,2674,2675],{"class":639},"0",[29,2677,250],{"class":180},[29,2679,624],{"class":35},[29,2681,373],{"class":180},[29,2683,509],{"class":208},[29,2685,2686],{"class":180},"))\n",[29,2688,2689,2692,2694,2696,2698,2700,2702,2704],{"class":31,"line":596},[29,2690,2691],{"class":176},"            for",[29,2693,491],{"class":208},[29,2695,250],{"class":180},[29,2697,496],{"class":208},[29,2699,422],{"class":180},[29,2701,501],{"class":176},[29,2703,102],{"class":208},[29,2705,277],{"class":180},[29,2707,2708,2711,2713,2715,2717,2719,2721,2724,2726,2728],{"class":31,"line":662},[29,2709,2710],{"class":208},"                items",[29,2712,671],{"class":180},[29,2714,674],{"class":35},[29,2716,373],{"class":180},[29,2718,1692],{"class":208},[29,2720,250],{"class":180},[29,2722,2723],{"class":35},"response",[29,2725,373],{"class":180},[29,2727,496],{"class":208},[29,2729,2686],{"class":180},[29,2731,2732],{"class":31,"line":692},[29,2733,2734],{"class":180},"            }\n",[29,2736,2737,2739,2742,2744],{"class":31,"line":707},[29,2738,554],{"class":176},[29,2740,2741],{"class":208}," items",[29,2743,250],{"class":180},[29,2745,457],{"class":208},[29,2747,2748],{"class":31,"line":766},[29,2749,2513],{"class":180},[29,2751,2752],{"class":31,"line":780},[29,2753,2754],{"class":180},"    })\n",[29,2756,2757],{"class":31,"line":785},[29,2758,309],{"class":180},[10,2760,2762],{"id":2761},"replace-the-starter-test","Replace the starter test",[15,2764,146,2765,2768],{},[26,2766,2767],{},"modules\u002Fusers\u002Fservice_test.go"," (the original test calls the starter Message method):",[19,2770,2772],{"className":153,"code":2771,"language":36,"meta":24,"style":24},"package users\n\nimport (\n    \"context\"\n    \"sync\"\n    \"testing\"\n)\n\nfunc TestConcurrentCreateAndRead(t *testing.T) {\n    s := NewService()\n    ctx := context.Background()\n    var wg sync.WaitGroup\n    for i := 0; i \u003C 10; i++ {\n        wg.Add(1)\n        go func() { defer wg.Done(); _, _ = s.Create(ctx, \"Ada\", \"ada@example.com\"); _, _ = s.List(ctx) }()\n    }\n    wg.Wait()\n    users, err := s.List(ctx)\n    if err != nil || len(users) != 1 {\n        t.Fatal(users, err)\n    }\n    if _, err = s.Get(ctx, users[0].ID); err != nil {\n        t.Fatal(err)\n    }\n}\n",[26,2773,2774,2780,2784,2790,2794,2798,2803,2807,2811,2835,2845,2861,2877,2907,2923,2997,3001,3013,3035,3061,3081,3085,3131,3145,3149],{"__ignoreMap":24},[29,2775,2776,2778],{"class":31,"line":32},[29,2777,161],{"class":58},[29,2779,165],{"class":164},[29,2781,2782],{"class":31,"line":46},[29,2783,171],{"emptyLinePlaceholder":170},[29,2785,2786,2788],{"class":31,"line":65},[29,2787,177],{"class":176},[29,2789,181],{"class":180},[29,2791,2792],{"class":31,"line":74},[29,2793,186],{"class":39},[29,2795,2796],{"class":31,"line":85},[29,2797,197],{"class":39},[29,2799,2800],{"class":31,"line":194},[29,2801,2802],{"class":39},"    \"testing\"\n",[29,2804,2805],{"class":31,"line":200},[29,2806,224],{"class":180},[29,2808,2809],{"class":31,"line":205},[29,2810,171],{"emptyLinePlaceholder":170},[29,2812,2813,2815,2818,2820,2823,2825,2828,2830,2833],{"class":31,"line":215},[29,2814,320],{"class":58},[29,2816,2817],{"class":35}," TestConcurrentCreateAndRead",[29,2819,373],{"class":180},[29,2821,2822],{"class":208},"t",[29,2824,2225],{"class":180},[29,2826,2827],{"class":164},"testing",[29,2829,125],{"class":180},[29,2831,2832],{"class":164},"T",[29,2834,410],{"class":180},[29,2836,2837,2839,2841,2843],{"class":31,"line":221},[29,2838,469],{"class":208},[29,2840,422],{"class":180},[29,2842,2308],{"class":35},[29,2844,482],{"class":180},[29,2846,2847,2850,2852,2854,2856,2859],{"class":31,"line":227},[29,2848,2849],{"class":208},"    ctx",[29,2851,422],{"class":180},[29,2853,1408],{"class":208},[29,2855,125],{"class":180},[29,2857,2858],{"class":35},"Background",[29,2860,482],{"class":180},[29,2862,2863,2866,2869,2872,2874],{"class":31,"line":232},[29,2864,2865],{"class":58},"    var",[29,2867,2868],{"class":208}," wg",[29,2870,2871],{"class":164}," sync",[29,2873,125],{"class":180},[29,2875,2876],{"class":164},"WaitGroup\n",[29,2878,2879,2881,2884,2886,2888,2891,2894,2897,2900,2902,2904],{"class":31,"line":267},[29,2880,488],{"class":176},[29,2882,2883],{"class":208}," i",[29,2885,422],{"class":180},[29,2887,2675],{"class":639},[29,2889,2890],{"class":180},"; ",[29,2892,2893],{"class":208},"i",[29,2895,2896],{"class":180}," \u003C ",[29,2898,2899],{"class":639},"10",[29,2901,2890],{"class":180},[29,2903,2893],{"class":208},[29,2905,2906],{"class":180},"++ {\n",[29,2908,2909,2912,2914,2917,2919,2921],{"class":31,"line":280},[29,2910,2911],{"class":208},"        wg",[29,2913,125],{"class":180},[29,2915,2916],{"class":35},"Add",[29,2918,373],{"class":180},[29,2920,640],{"class":639},[29,2922,224],{"class":180},[29,2924,2925,2928,2930,2933,2936,2938,2940,2943,2945,2947,2949,2951,2953,2955,2957,2959,2961,2963,2965,2968,2970,2973,2976,2978,2980,2982,2984,2986,2988,2990,2992,2994],{"class":31,"line":294},[29,2926,2927],{"class":176},"        go",[29,2929,1403],{"class":58},[29,2931,2932],{"class":180},"() { ",[29,2934,2935],{"class":176},"defer",[29,2937,2868],{"class":208},[29,2939,125],{"class":180},[29,2941,2942],{"class":35},"Done",[29,2944,432],{"class":180},[29,2946,1635],{"class":208},[29,2948,250],{"class":180},[29,2950,1635],{"class":208},[29,2952,671],{"class":180},[29,2954,629],{"class":208},[29,2956,125],{"class":180},[29,2958,370],{"class":35},[29,2960,373],{"class":180},[29,2962,376],{"class":208},[29,2964,250],{"class":180},[29,2966,2967],{"class":39},"\"Ada\"",[29,2969,250],{"class":180},[29,2971,2972],{"class":39},"\"ada@example.com\"",[29,2974,2975],{"class":180},"); ",[29,2977,1635],{"class":208},[29,2979,250],{"class":180},[29,2981,1635],{"class":208},[29,2983,671],{"class":180},[29,2985,629],{"class":208},[29,2987,125],{"class":180},[29,2989,800],{"class":35},[29,2991,373],{"class":180},[29,2993,376],{"class":208},[29,2995,2996],{"class":180},") }()\n",[29,2998,2999],{"class":31,"line":306},[29,3000,463],{"class":180},[29,3002,3003,3006,3008,3011],{"class":31,"line":312},[29,3004,3005],{"class":208},"    wg",[29,3007,125],{"class":180},[29,3009,3010],{"class":35},"Wait",[29,3012,482],{"class":180},[29,3014,3015,3017,3019,3021,3023,3025,3027,3029,3031,3033],{"class":31,"line":317},[29,3016,297],{"class":208},[29,3018,250],{"class":180},[29,3020,435],{"class":208},[29,3022,422],{"class":180},[29,3024,629],{"class":208},[29,3026,125],{"class":180},[29,3028,800],{"class":35},[29,3030,373],{"class":180},[29,3032,376],{"class":208},[29,3034,224],{"class":180},[29,3036,3037,3039,3041,3043,3045,3048,3050,3052,3054,3057,3059],{"class":31,"line":346},[29,3038,416],{"class":176},[29,3040,419],{"class":208},[29,3042,438],{"class":180},[29,3044,441],{"class":58},[29,3046,3047],{"class":180}," || ",[29,3049,624],{"class":35},[29,3051,373],{"class":180},[29,3053,509],{"class":208},[29,3055,3056],{"class":180},") != ",[29,3058,640],{"class":639},[29,3060,277],{"class":180},[29,3062,3063,3066,3068,3071,3073,3075,3077,3079],{"class":31,"line":351},[29,3064,3065],{"class":208},"        t",[29,3067,125],{"class":180},[29,3069,3070],{"class":35},"Fatal",[29,3072,373],{"class":180},[29,3074,509],{"class":208},[29,3076,250],{"class":180},[29,3078,435],{"class":208},[29,3080,224],{"class":180},[29,3082,3083],{"class":31,"line":413},[29,3084,463],{"class":180},[29,3086,3087,3089,3091,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3114,3116,3119,3121,3123,3125,3127,3129],{"class":31,"line":446},[29,3088,416],{"class":176},[29,3090,491],{"class":208},[29,3092,250],{"class":180},[29,3094,435],{"class":208},[29,3096,671],{"class":180},[29,3098,629],{"class":208},[29,3100,125],{"class":180},[29,3102,951],{"class":35},[29,3104,373],{"class":180},[29,3106,376],{"class":208},[29,3108,250],{"class":180},[29,3110,509],{"class":208},[29,3112,3113],{"class":180},"[",[29,3115,2675],{"class":639},[29,3117,3118],{"class":180},"].",[29,3120,247],{"class":208},[29,3122,2975],{"class":180},[29,3124,435],{"class":208},[29,3126,438],{"class":180},[29,3128,441],{"class":58},[29,3130,277],{"class":180},[29,3132,3133,3135,3137,3139,3141,3143],{"class":31,"line":460},[29,3134,3065],{"class":208},[29,3136,125],{"class":180},[29,3138,3070],{"class":35},[29,3140,373],{"class":180},[29,3142,435],{"class":208},[29,3144,224],{"class":180},[29,3146,3147],{"class":31,"line":466},[29,3148,463],{"class":180},[29,3150,3151],{"class":31,"line":485},[29,3152,309],{"class":180},[10,3154,3156],{"id":3155},"run-your-api","Run your API",[19,3158,3160],{"className":21,"code":3159,"language":23,"meta":24,"style":24},"go mod tidy\ngo tool gonex check\ngo tool gonex run\n",[26,3161,3162,3170,3181],{"__ignoreMap":24},[29,3163,3164,3166,3168],{"class":31,"line":32},[29,3165,36],{"class":35},[29,3167,79],{"class":39},[29,3169,82],{"class":39},[29,3171,3172,3174,3176,3178],{"class":31,"line":46},[29,3173,36],{"class":35},[29,3175,90],{"class":39},[29,3177,93],{"class":39},[29,3179,3180],{"class":39}," check\n",[29,3182,3183,3185,3187,3189],{"class":31,"line":65},[29,3184,36],{"class":35},[29,3186,90],{"class":39},[29,3188,93],{"class":39},[29,3190,3191],{"class":39}," run\n",[15,3193,3194,3195,125],{},"The terminal shows your local server and OpenAPI URLs. The standard generated configuration reads HTTP_ADDRESS and log settings; see ",[121,3196,3198],{"href":3197},"\u002Fdocs\u002Fmain\u002Flogging\u002F","logging",[15,3200,3201,3202,3205,3206,3209],{},"Create a user (POSIX shell; on PowerShell use ",[26,3203,3204],{},"curl.exe"," with the appropriate JSON quoting or ",[26,3207,3208],{},"Invoke-RestMethod","):",[19,3211,3213],{"className":21,"code":3212,"language":23,"meta":24,"style":24},"curl -i http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"name\":\"Ada\",\"email\":\"ada@example.com\"}'\n",[26,3214,3215,3230,3240],{"__ignoreMap":24},[29,3216,3217,3220,3223,3226],{"class":31,"line":32},[29,3218,3219],{"class":35},"curl",[29,3221,3222],{"class":58}," -i",[29,3224,3225],{"class":39}," http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers",[29,3227,3229],{"class":3228},"sbve-"," \\\n",[29,3231,3232,3235,3238],{"class":31,"line":46},[29,3233,3234],{"class":58},"  -H",[29,3236,3237],{"class":39}," 'Content-Type: application\u002Fjson'",[29,3239,3229],{"class":3228},[29,3241,3242,3245],{"class":31,"line":65},[29,3243,3244],{"class":58},"  -d",[29,3246,3247],{"class":39}," '{\"name\":\"Ada\",\"email\":\"ada@example.com\"}'\n",[15,3249,3250,3251,2090],{},"The response is ",[26,3252,3253],{},"201 Created",[19,3255,3259],{"className":3256,"code":3257,"language":3258,"meta":24,"style":24},"language-json shiki shiki-themes light-plus light-plus dark-plus","{\"id\":\"1\",\"name\":\"Ada\",\"email\":\"ada@example.com\"}\n","json",[26,3260,3261],{"__ignoreMap":24},[29,3262,3263,3265,3269,3271,3274,3277,3280,3282,3284,3286,3289,3291,3293],{"class":31,"line":32},[29,3264,606],{"class":180},[29,3266,3268],{"class":3267},"s9Kr7","\"id\"",[29,3270,2090],{"class":180},[29,3272,3273],{"class":39},"\"1\"",[29,3275,3276],{"class":180},",",[29,3278,3279],{"class":3267},"\"name\"",[29,3281,2090],{"class":180},[29,3283,2967],{"class":39},[29,3285,3276],{"class":180},[29,3287,3288],{"class":3267},"\"email\"",[29,3290,2090],{"class":180},[29,3292,2972],{"class":39},[29,3294,309],{"class":180},[19,3296,3298],{"className":21,"code":3297,"language":23,"meta":24,"style":24},"curl http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers\ncurl http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers\u002F1\ncurl http:\u002F\u002F127.0.0.1:8080\u002Fopenapi.json\n",[26,3299,3300,3307,3314],{"__ignoreMap":24},[29,3301,3302,3304],{"class":31,"line":32},[29,3303,3219],{"class":35},[29,3305,3306],{"class":39}," http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers\n",[29,3308,3309,3311],{"class":31,"line":46},[29,3310,3219],{"class":35},[29,3312,3313],{"class":39}," http:\u002F\u002F127.0.0.1:8080\u002Fapi\u002Fusers\u002F1\n",[29,3315,3316,3318],{"class":31,"line":65},[29,3317,3219],{"class":35},[29,3319,3320],{"class":39}," http:\u002F\u002F127.0.0.1:8080\u002Fopenapi.json\n",[3322,3323,3324,3337],"table",{},[3325,3326,3327],"thead",{},[3328,3329,3330,3334],"tr",{},[3331,3332,3333],"th",{},"Request",[3331,3335,3336],{},"Expected behavior",[3338,3339,3340,3355,3363,3371,3379,3387],"tbody",{},[3328,3341,3342,3349],{},[3343,3344,3345,3346],"td",{},"GET ",[26,3347,3348],{},"\u002Fapi\u002Fusers",[3343,3350,3351,3352,3354],{},"200, an ",[26,3353,1692],{}," array, including an empty array before creation",[3328,3356,3357,3360],{},[3343,3358,3359],{},"POST valid user",[3343,3361,3362],{},"201, created user",[3328,3364,3365,3368],{},[3343,3366,3367],{},"POST same email twice",[3343,3369,3370],{},"409 conflict",[3328,3372,3373,3376],{},[3343,3374,3375],{},"POST invalid name\u002Femail",[3343,3377,3378],{},"422 validation error",[3328,3380,3381,3384],{},[3343,3382,3383],{},"POST malformed JSON or unknown fields",[3343,3385,3386],{},"400 invalid request",[3328,3388,3389,3392],{},[3343,3390,3391],{},"GET unknown user",[3343,3393,3394],{},"404 not found",[15,3396,3397,3398,3401],{},"The service emits a ",[26,3399,3400],{},"user created"," event with module\u002Fuser ID; its request ID matches the HTTP completion event. Default request logs omit body, token and query-string values. Business log fields are explicit.",[10,3403,3405],{"id":3404},"next-steps","Next steps",[15,3407,3408,3409,250,3413,3417,3418,3422,3423,125],{},"This is an explicit resource API, not an automatic ModelViewSet. It has no authentication, pagination, update\u002Fdelete actions or persistent storage. Add those deliberately using ",[121,3410,3412],{"href":3411},"\u002Fdocs\u002Fmain\u002Fsecurity\u002F","security",[121,3414,3416],{"href":3415},"\u002Fdocs\u002Fmain\u002Fdatabase\u002F","database adapters"," and ",[121,3419,3421],{"href":3420},"\u002Fdocs\u002Fmain\u002Fhttp\u002F","HTTP contracts",". Connect a frontend through the ",[121,3424,3426],{"href":3425},"\u002Fdocs\u002Fmain\u002Ffrontend\u002F","JSON API",[3428,3429,3430],"style",{},"html pre.shiki code .stxUP, html code.shiki .stxUP{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#569CD6}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 .s_Yst, html code.shiki .s_Yst{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#D4D4D4}html pre.shiki code .sFD8J, html code.shiki .sFD8J{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#CE9178}html pre.shiki code .sswaR, html code.shiki .sswaR{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#9CDCFE}html pre.shiki code .swoLU, html code.shiki .swoLU{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#DCDCAA}html pre.shiki code .s-S-M, html code.shiki .s-S-M{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#B5CEA8}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 .syj1l, html code.shiki .syj1l{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#4FC1FF}html pre.shiki code .sbve-, html code.shiki .sbve-{--shiki-light:#EE0000;--shiki-default:#EE0000;--shiki-dark:#D7BA7D}html pre.shiki code .s9Kr7, html code.shiki .s9Kr7{--shiki-light:#0451A5;--shiki-default:#0451A5;--shiki-dark:#9CDCFE}",{"title":24,"searchDepth":46,"depth":46,"links":3432},[3433,3434,3435,3436,3437,3438,3439,3440,3441],{"id":12,"depth":46,"text":13},{"id":142,"depth":46,"text":143},{"id":1151,"depth":46,"text":1152},{"id":1351,"depth":46,"text":1352},{"id":1776,"depth":46,"text":1777},{"id":2152,"depth":46,"text":2153},{"id":2761,"depth":46,"text":2762},{"id":3155,"depth":46,"text":3156},{"id":3404,"depth":46,"text":3405},"Build create, list and get user endpoints in a CLI-generated Gonex app, using schemas.go validation, explicit services and OpenAPI.","md","GETTING STARTED",{},"\u002Fdocs\u002Fmain\u002Fbuilding-api","build",{"title":5,"description":3442},null,"docs\u002Fmain\u002Fbuilding-api","main","95VZQ1dWinAL3NxIhfZsJ9WMd8tkKPd9W5uXOCWkUzs",1792521640250]