diff --git a/tools/goctl/api/gogen/genroutes.go b/tools/goctl/api/gogen/genroutes.go index abd0c001..cd41b220 100644 --- a/tools/goctl/api/gogen/genroutes.go +++ b/tools/goctl/api/gogen/genroutes.go @@ -39,12 +39,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { ) var mapping = map[string]string{ - "delete": "http.MethodDelete", - "get": "http.MethodGet", - "head": "http.MethodHead", - "post": "http.MethodPost", - "put": "http.MethodPut", - "patch": "http.MethodPatch", + "delete": "http.MethodDelete", + "get": "http.MethodGet", + "head": "http.MethodHead", + "post": "http.MethodPost", + "put": "http.MethodPut", + "patch": "http.MethodPatch", + "connect": "http.MethodConnect", + "options": "http.MethodOptions", + "trace": "http.MethodTrace", } type ( diff --git a/tools/goctl/api/parser/g4/ast/api.go b/tools/goctl/api/parser/g4/ast/api.go index 4bf94732..2694c6d2 100644 --- a/tools/goctl/api/parser/g4/ast/api.go +++ b/tools/goctl/api/parser/g4/ast/api.go @@ -2,11 +2,14 @@ package ast import ( "fmt" + "path" "sort" "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +const prefixKey = "prefix" + // Api describes syntax for api type Api struct { LinePrefix string @@ -49,8 +52,15 @@ func (v *ApiVisitor) acceptService(root, final *Api) { } v.duplicateServerItemCheck(service) + var prefix string + if service.AtServer != nil { + p := service.AtServer.Kv.Get(prefixKey) + if p != nil { + prefix = p.Text() + } + } for _, route := range service.ServiceApi.ServiceRoute { - uniqueRoute := fmt.Sprintf("%s %s", route.Route.Method.Text(), route.Route.Path.Text()) + uniqueRoute := fmt.Sprintf("%s %s", route.Route.Method.Text(), path.Join(prefix, route.Route.Path.Text())) if _, ok := final.routeM[uniqueRoute]; ok { v.panic(route.Route.Method, fmt.Sprintf("duplicate route '%s'", uniqueRoute)) } diff --git a/tools/goctl/api/parser/g4/ast/apiparser.go b/tools/goctl/api/parser/g4/ast/apiparser.go index bdf5e91c..b0c9c6a5 100644 --- a/tools/goctl/api/parser/g4/ast/apiparser.go +++ b/tools/goctl/api/parser/g4/ast/apiparser.go @@ -3,6 +3,7 @@ package ast import ( "fmt" "io/ioutil" + "path" "path/filepath" "strings" @@ -113,13 +114,13 @@ func (p *Parser) parse(filename, content string) (*Api, error) { apiAstList = append(apiAstList, root) for _, imp := range root.Import { dir := filepath.Dir(p.src) - path := filepath.Join(dir, imp.Value.Text()) - data, err := p.readContent(path) + imp := filepath.Join(dir, imp.Value.Text()) + data, err := p.readContent(imp) if err != nil { return nil, err } - nestedApi, err := p.invoke(path, data) + nestedApi, err := p.invoke(imp, data) if err != nil { return nil, err } @@ -196,8 +197,8 @@ func (p *Parser) valid(mainApi, nestedApi *Api) error { if handler.IsNotNil() { handlerName := handler.Text() handlerMap[handlerName] = Holder - path := fmt.Sprintf("%s://%s", g.Route.Method.Text(), g.Route.Path.Text()) - routeMap[path] = Holder + route := fmt.Sprintf("%s://%s", g.Route.Method.Text(), g.Route.Path.Text()) + routeMap[route] = Holder } } @@ -239,6 +240,13 @@ func (p *Parser) valid(mainApi, nestedApi *Api) error { func (p *Parser) duplicateRouteCheck(nestedApi *Api, mainHandlerMap, mainRouteMap map[string]PlaceHolder) error { for _, each := range nestedApi.Service { + var prefix string + if each.AtServer != nil { + p := each.AtServer.Kv.Get(prefixKey) + if p != nil { + prefix = p.Text() + } + } for _, r := range each.ServiceApi.ServiceRoute { handler := r.GetHandler() if !handler.IsNotNil() { @@ -250,8 +258,8 @@ func (p *Parser) duplicateRouteCheck(nestedApi *Api, mainHandlerMap, mainRouteMa nestedApi.LinePrefix, handler.Line(), handler.Column(), handler.Text()) } - path := fmt.Sprintf("%s://%s", r.Route.Method.Text(), r.Route.Path.Text()) - if _, ok := mainRouteMap[path]; ok { + p := fmt.Sprintf("%s://%s", r.Route.Method.Text(), path.Join(prefix, r.Route.Path.Text())) + if _, ok := mainRouteMap[p]; ok { return fmt.Errorf("%s line %d:%d duplicate route '%s'", nestedApi.LinePrefix, r.Route.Method.Line(), r.Route.Method.Column(), r.Route.Method.Text()+" "+r.Route.Path.Text()) }