github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/cmd/internal/svc/codegen/httphandler.go (about) 1 package codegen 2 3 import ( 4 "bytes" 5 "github.com/unionj-cloud/go-doudou/toolkit/sliceutils" 6 "github.com/unionj-cloud/go-doudou/toolkit/stringutils" 7 "github.com/unionj-cloud/go-doudou/version" 8 "os" 9 "path/filepath" 10 "strings" 11 "text/template" 12 13 "github.com/iancoleman/strcase" 14 "github.com/sirupsen/logrus" 15 "github.com/unionj-cloud/go-doudou/cmd/internal/astutils" 16 ) 17 18 var httpHandlerTmpl = `/** 19 * Generated by go-doudou {{.Version}}. 20 * Don't edit! 21 */ 22 package httpsrv 23 24 import ( 25 ddmodel "github.com/unionj-cloud/go-doudou/framework/http/model" 26 "net/http" 27 "os" 28 ) 29 30 type {{.Meta.Name}}Handler interface { 31 {{- range $m := .Meta.Methods }} 32 {{$m.Name}}(w http.ResponseWriter, r *http.Request) 33 {{- end }} 34 } 35 36 func Routes(handler {{.Meta.Name}}Handler) []ddmodel.Route { 37 return []ddmodel.Route{ 38 {{- range $m := .Meta.Methods }} 39 { 40 Name: "{{$m.Name}}", 41 Method: "{{$m.Name | httpMethod}}", 42 Pattern: {{- if eq $.RoutePatternStrategy 1}}"/{{$.Meta.Name | lower}}/{{$m.Name | noSplitPattern}}",{{- else }}"/{{$m.Name | pattern}}",{{- end }} 43 HandlerFunc: handler.{{$m.Name}}, 44 }, 45 {{- end }} 46 } 47 } 48 49 50 var RouteAnnotationStore = ddmodel.AnnotationStore{ 51 {{- range $m := .Meta.Methods }} 52 {{- if $m.Annotations }} 53 "{{$m.Name}}": { 54 {{- range $a := $m.Annotations }} 55 { 56 Name: "{{ $a.Name }}", 57 {{- if $a.Params }} 58 Params: []string{ 59 {{- range $p := $a.Params }} 60 "{{ $p }}", 61 {{- end }} 62 }, 63 {{- end }} 64 }, 65 {{- end }} 66 }, 67 {{- end }} 68 {{- end }} 69 } 70 ` 71 72 func pattern(method string) string { 73 httpMethods := []string{"GET", "POST", "PUT", "DELETE"} 74 snake := strcase.ToSnake(strings.ReplaceAll(method, "_", ".")) 75 splits := strings.Split(snake, "_") 76 head := strings.ToUpper(splits[0]) 77 if sliceutils.StringContains(httpMethods, head) { 78 splits = splits[1:] 79 } 80 clean := sliceutils.StringFilter(splits, func(item string) bool { 81 return stringutils.IsNotEmpty(item) 82 }) 83 return strings.Join(clean, "/") 84 } 85 86 func noSplitPattern(method string) string { 87 httpMethods := []string{"GET", "POST", "PUT", "DELETE"} 88 snake := strcase.ToSnake(method) 89 splits := strings.Split(snake, "_") 90 head := strings.ToUpper(splits[0]) 91 for _, m := range httpMethods { 92 if head == m { 93 return strings.ToLower(method[len(m):]) 94 } 95 } 96 return strings.ToLower(method) 97 } 98 99 func httpMethod(method string) string { 100 httpMethods := []string{"GET", "POST", "PUT", "DELETE"} 101 snake := strcase.ToSnake(method) 102 splits := strings.Split(snake, "_") 103 head := strings.ToUpper(splits[0]) 104 for _, m := range httpMethods { 105 if head == m { 106 return m 107 } 108 } 109 return "POST" 110 } 111 112 // GenHttpHandler generates http handler interface and routes 113 func GenHttpHandler(dir string, ic astutils.InterfaceCollector, routePatternStrategy int) { 114 var ( 115 err error 116 handlerfile string 117 f *os.File 118 tpl *template.Template 119 httpDir string 120 source string 121 sqlBuf bytes.Buffer 122 fi os.FileInfo 123 ) 124 httpDir = filepath.Join(dir, "transport/httpsrv") 125 if err = os.MkdirAll(httpDir, os.ModePerm); err != nil { 126 panic(err) 127 } 128 129 handlerfile = filepath.Join(httpDir, "handler.go") 130 fi, err = os.Stat(handlerfile) 131 if err != nil && !os.IsNotExist(err) { 132 panic(err) 133 } 134 if fi != nil { 135 logrus.Warningln("file handler.go will be overwritten") 136 } 137 if f, err = os.Create(handlerfile); err != nil { 138 panic(err) 139 } 140 defer f.Close() 141 142 funcMap := make(map[string]interface{}) 143 funcMap["httpMethod"] = httpMethod 144 funcMap["pattern"] = pattern 145 funcMap["noSplitPattern"] = noSplitPattern 146 funcMap["lower"] = strings.ToLower 147 if tpl, err = template.New("handler.go.tmpl").Funcs(funcMap).Parse(httpHandlerTmpl); err != nil { 148 panic(err) 149 } 150 if err = tpl.Execute(&sqlBuf, struct { 151 RoutePatternStrategy int 152 Meta astutils.InterfaceMeta 153 Version string 154 }{ 155 RoutePatternStrategy: routePatternStrategy, 156 Meta: ic.Interfaces[0], 157 Version: version.Release, 158 }); err != nil { 159 panic(err) 160 } 161 source = strings.TrimSpace(sqlBuf.String()) 162 astutils.FixImport([]byte(source), handlerfile) 163 }