go-zero/tools/goctl/api/gogen/genroutes.go

223 lines
5.5 KiB
Go
Raw Normal View History

2020-07-29 17:11:41 +08:00
package gogen
import (
"fmt"
"os"
2020-07-29 17:11:41 +08:00
"path"
"sort"
"strings"
"text/template"
2020-08-08 16:40:10 +08:00
"github.com/tal-tech/go-zero/core/collection"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
"github.com/tal-tech/go-zero/tools/goctl/config"
2020-08-08 16:40:10 +08:00
"github.com/tal-tech/go-zero/tools/goctl/util"
"github.com/tal-tech/go-zero/tools/goctl/util/format"
2020-08-08 16:40:10 +08:00
"github.com/tal-tech/go-zero/tools/goctl/vars"
2020-07-29 17:11:41 +08:00
)
const (
routesFilename = "routes"
routesTemplate = `// Code generated by goctl. DO NOT EDIT.
2020-07-29 17:11:41 +08:00
package handler
import (
"net/http"
{{.importPackages}}
)
2020-07-31 17:03:19 +08:00
func RegisterHandlers(engine *rest.Server, serverCtx *svc.ServiceContext) {
2020-07-29 17:11:41 +08:00
{{.routesAdditions}}
}
`
routesAdditionTemplate = `
engine.AddRoutes(
{{.routes}} {{.jwt}}{{.signature}} {{.prefix}}
)
2020-07-29 17:11:41 +08:00
`
)
var mapping = map[string]string{
"delete": "http.MethodDelete",
"get": "http.MethodGet",
"head": "http.MethodHead",
"post": "http.MethodPost",
"put": "http.MethodPut",
"patch": "http.MethodPatch",
2020-07-29 17:11:41 +08:00
}
type (
group struct {
routes []route
jwtEnabled bool
signatureEnabled bool
authName string
middlewares []string
prefix string
2020-07-29 17:11:41 +08:00
}
route struct {
method string
path string
handler string
}
)
func genRoutes(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error {
2020-07-29 17:11:41 +08:00
var builder strings.Builder
groups, err := getRoutes(api)
if err != nil {
return err
}
gt := template.Must(template.New("groupTemplate").Parse(routesAdditionTemplate))
for _, g := range groups {
var gbuilder strings.Builder
gbuilder.WriteString("[]rest.Route{")
2020-07-29 17:11:41 +08:00
for _, r := range g.routes {
fmt.Fprintf(&gbuilder, `
{
Method: %s,
Path: "%s",
Handler: %s,
},`,
r.method, r.path, r.handler)
}
2020-07-31 17:11:59 +08:00
var jwt string
2020-07-29 17:11:41 +08:00
if g.jwtEnabled {
jwt = fmt.Sprintf("\n rest.WithJwt(serverCtx.Config.%s.AccessSecret),", g.authName)
2020-07-29 17:11:41 +08:00
}
var signature, prefix string
2020-07-29 17:11:41 +08:00
if g.signatureEnabled {
2021-02-20 19:50:03 +08:00
signature = "\n rest.WithSignature(serverCtx.Config.Signature),"
2020-07-29 17:11:41 +08:00
}
if len(g.prefix) > 0 {
prefix = fmt.Sprintf(`
rest.WithPrefix("%s"),`, g.prefix)
}
var routes string
if len(g.middlewares) > 0 {
gbuilder.WriteString("\n}...,")
2021-04-15 19:49:17 +08:00
params := g.middlewares
for i := range params {
params[i] = "serverCtx." + params[i]
}
2021-04-15 19:49:17 +08:00
middlewareStr := strings.Join(params, ", ")
routes = fmt.Sprintf("rest.WithMiddlewares(\n[]rest.Middleware{ %s }, \n %s \n),",
middlewareStr, strings.TrimSpace(gbuilder.String()))
} else {
gbuilder.WriteString("\n},")
routes = strings.TrimSpace(gbuilder.String())
}
2020-07-29 17:11:41 +08:00
if err := gt.Execute(&builder, map[string]string{
"routes": routes,
2020-07-29 17:11:41 +08:00
"jwt": jwt,
"signature": signature,
"prefix": prefix,
2020-07-29 17:11:41 +08:00
}); err != nil {
return err
}
}
routeFilename, err := format.FileNamingFormat(cfg.NamingFormat, routesFilename)
if err != nil {
return err
}
routeFilename = routeFilename + ".go"
filename := path.Join(dir, handlerDir, routeFilename)
os.Remove(filename)
2020-07-29 17:11:41 +08:00
2021-01-09 00:17:23 +08:00
return genFile(fileGenConfig{
dir: dir,
subdir: handlerDir,
filename: routeFilename,
templateName: "routesTemplate",
category: "",
templateFile: "",
builtinTemplate: routesTemplate,
data: map[string]string{
"importPackages": genRouteImports(rootPkg, api),
2021-01-09 00:17:23 +08:00
"routesAdditions": strings.TrimSpace(builder.String()),
},
2020-07-29 17:11:41 +08:00
})
}
func genRouteImports(parentPkg string, api *spec.ApiSpec) string {
2021-04-15 19:49:17 +08:00
importSet := collection.NewSet()
2020-08-10 17:26:47 +08:00
importSet.AddStr(fmt.Sprintf("\"%s\"", util.JoinPackages(parentPkg, contextDir)))
2020-07-29 17:11:41 +08:00
for _, group := range api.Service.Groups {
for _, route := range group.Routes {
folder := route.GetAnnotation(groupProperty)
if len(folder) == 0 {
folder = group.GetAnnotation(groupProperty)
if len(folder) == 0 {
2020-07-29 17:11:41 +08:00
continue
}
}
importSet.AddStr(fmt.Sprintf("%s \"%s\"", toPrefix(folder), util.JoinPackages(parentPkg, handlerDir, folder)))
2020-07-29 17:11:41 +08:00
}
}
imports := importSet.KeysStr()
sort.Strings(imports)
2020-08-27 14:40:05 +08:00
projectSection := strings.Join(imports, "\n\t")
2021-02-20 19:50:03 +08:00
depSection := fmt.Sprintf("\"%s/rest\"", vars.ProjectOpenSourceURL)
2020-08-27 14:40:05 +08:00
return fmt.Sprintf("%s\n\n\t%s", projectSection, depSection)
2020-07-29 17:11:41 +08:00
}
func getRoutes(api *spec.ApiSpec) ([]group, error) {
var routes []group
for _, g := range api.Service.Groups {
var groupedRoutes group
for _, r := range g.Routes {
handler := getHandlerName(r)
handler = handler + "(serverCtx)"
folder := r.GetAnnotation(groupProperty)
if len(folder) > 0 {
handler = toPrefix(folder) + "." + strings.ToUpper(handler[:1]) + handler[1:]
2020-07-29 17:11:41 +08:00
} else {
folder = g.GetAnnotation(groupProperty)
if len(folder) > 0 {
handler = toPrefix(folder) + "." + strings.ToUpper(handler[:1]) + handler[1:]
2020-07-29 17:11:41 +08:00
}
}
groupedRoutes.routes = append(groupedRoutes.routes, route{
method: mapping[r.Method],
path: r.Path,
handler: handler,
})
}
jwt := g.GetAnnotation("jwt")
if len(jwt) > 0 {
groupedRoutes.authName = jwt
groupedRoutes.jwtEnabled = true
}
2021-02-20 19:50:03 +08:00
signature := g.GetAnnotation("signature")
if signature == "true" {
groupedRoutes.signatureEnabled = true
}
middleware := g.GetAnnotation("middleware")
if len(middleware) > 0 {
2021-09-29 13:09:20 +08:00
groupedRoutes.middlewares = append(groupedRoutes.middlewares,
strings.Split(middleware, ",")...)
}
prefix := g.GetAnnotation(spec.RoutePrefixKey)
prefix = strings.TrimSpace(prefix)
prefix = strings.ReplaceAll(prefix, `"`, "")
prefix = path.Join("/", prefix)
groupedRoutes.prefix = prefix
2020-07-29 17:11:41 +08:00
routes = append(routes, groupedRoutes)
}
return routes, nil
}
func toPrefix(folder string) string {
return strings.ReplaceAll(folder, "/", "")
}