genhandlers.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package gogen
  2. import (
  3. "fmt"
  4. "path"
  5. "strings"
  6. "github.com/tal-tech/go-zero/tools/goctl/api/spec"
  7. "github.com/tal-tech/go-zero/tools/goctl/config"
  8. "github.com/tal-tech/go-zero/tools/goctl/internal/version"
  9. "github.com/tal-tech/go-zero/tools/goctl/util"
  10. "github.com/tal-tech/go-zero/tools/goctl/util/format"
  11. "github.com/tal-tech/go-zero/tools/goctl/vars"
  12. )
  13. const (
  14. defaultLogicPackage = "logic"
  15. handlerTemplate = `package {{.PkgName}}
  16. import (
  17. "net/http"
  18. {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}}
  19. {{.ImportPackages}}
  20. )
  21. func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
  22. return func(w http.ResponseWriter, r *http.Request) {
  23. {{if .HasRequest}}var req types.{{.RequestType}}
  24. if err := httpx.Parse(r, &req); err != nil {
  25. httpx.Error(w, err)
  26. return
  27. }
  28. {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
  29. {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})
  30. if err != nil {
  31. httpx.Error(w, err)
  32. } else {
  33. {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}}
  34. }
  35. }
  36. }
  37. `
  38. )
  39. type handlerInfo struct {
  40. PkgName string
  41. ImportPackages string
  42. HandlerName string
  43. RequestType string
  44. LogicName string
  45. LogicType string
  46. Call string
  47. HasResp bool
  48. HasRequest bool
  49. After1_1_10 bool
  50. }
  51. func genHandler(dir, rootPkg string, cfg *config.Config, group spec.Group, route spec.Route) error {
  52. handler := getHandlerName(route)
  53. handlerPath := getHandlerFolderPath(group, route)
  54. pkgName := handlerPath[strings.LastIndex(handlerPath, "/")+1:]
  55. logicName := defaultLogicPackage
  56. if handlerPath != handlerDir {
  57. handler = strings.Title(handler)
  58. logicName = pkgName
  59. }
  60. parentPkg, err := getParentPackage(dir)
  61. if err != nil {
  62. return err
  63. }
  64. goctlVersion := version.GetGoctlVersion()
  65. // todo(anqiansong): This will be removed after a certain number of production versions of goctl (probably 5)
  66. after1_1_10 := version.IsVersionGreaterThan(goctlVersion, "1.1.10")
  67. return doGenToFile(dir, handler, cfg, group, route, handlerInfo{
  68. PkgName: pkgName,
  69. ImportPackages: genHandlerImports(group, route, parentPkg),
  70. HandlerName: handler,
  71. After1_1_10: after1_1_10,
  72. RequestType: util.Title(route.RequestTypeName()),
  73. LogicName: logicName,
  74. LogicType: strings.Title(getLogicName(route)),
  75. Call: strings.Title(strings.TrimSuffix(handler, "Handler")),
  76. HasResp: len(route.ResponseTypeName()) > 0,
  77. HasRequest: len(route.RequestTypeName()) > 0,
  78. })
  79. }
  80. func doGenToFile(dir, handler string, cfg *config.Config, group spec.Group,
  81. route spec.Route, handleObj handlerInfo) error {
  82. filename, err := format.FileNamingFormat(cfg.NamingFormat, handler)
  83. if err != nil {
  84. return err
  85. }
  86. return genFile(fileGenConfig{
  87. dir: dir,
  88. subdir: getHandlerFolderPath(group, route),
  89. filename: filename + ".go",
  90. templateName: "handlerTemplate",
  91. category: category,
  92. templateFile: handlerTemplateFile,
  93. builtinTemplate: handlerTemplate,
  94. data: handleObj,
  95. })
  96. }
  97. func genHandlers(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
  98. for _, group := range api.Service.Groups {
  99. for _, route := range group.Routes {
  100. if err := genHandler(dir, rootPkg, cfg, group, route); err != nil {
  101. return err
  102. }
  103. }
  104. }
  105. return nil
  106. }
  107. func genHandlerImports(group spec.Group, route spec.Route, parentPkg string) string {
  108. var imports []string
  109. imports = append(imports, fmt.Sprintf("\"%s\"",
  110. util.JoinPackages(parentPkg, getLogicFolderPath(group, route))))
  111. imports = append(imports, fmt.Sprintf("\"%s\"", util.JoinPackages(parentPkg, contextDir)))
  112. if len(route.RequestTypeName()) > 0 {
  113. imports = append(imports, fmt.Sprintf("\"%s\"\n", util.JoinPackages(parentPkg, typesDir)))
  114. }
  115. currentVersion := version.GetGoctlVersion()
  116. // todo(anqiansong): This will be removed after a certain number of production versions of goctl (probably 5)
  117. if !version.IsVersionGreaterThan(currentVersion, "1.1.10") {
  118. imports = append(imports, fmt.Sprintf("\"%s/rest/httpx\"", vars.ProjectOpenSourceURL))
  119. }
  120. return strings.Join(imports, "\n\t")
  121. }
  122. func getHandlerBaseName(route spec.Route) (string, error) {
  123. handler := route.Handler
  124. handler = strings.TrimSpace(handler)
  125. handler = strings.TrimSuffix(handler, "handler")
  126. handler = strings.TrimSuffix(handler, "Handler")
  127. return handler, nil
  128. }
  129. func getHandlerFolderPath(group spec.Group, route spec.Route) string {
  130. folder := route.GetAnnotation(groupProperty)
  131. if len(folder) == 0 {
  132. folder = group.GetAnnotation(groupProperty)
  133. if len(folder) == 0 {
  134. return handlerDir
  135. }
  136. }
  137. folder = strings.TrimPrefix(folder, "/")
  138. folder = strings.TrimSuffix(folder, "/")
  139. return path.Join(handlerDir, folder)
  140. }
  141. func getHandlerName(route spec.Route) string {
  142. handler, err := getHandlerBaseName(route)
  143. if err != nil {
  144. panic(err)
  145. }
  146. return handler + "Handler"
  147. }
  148. func getLogicName(route spec.Route) string {
  149. handler, err := getHandlerBaseName(route)
  150. if err != nil {
  151. panic(err)
  152. }
  153. return handler + "Logic"
  154. }