Fix Dart API generation bugs; Add ability to generate API for path parameters (#2887)

* Fix bug in dartgen: Import path should match the generated api filename

* Use Route.HandlerName as generated dart API function name

Reasons:
- There is bug when using url path name as function name, because it may have invalid characters such as ":"
- Switching to HandlerName aligns with other languages such as typescript generation

* [DartGen] Add ability to generate api for url path parameters such as /path/:param
master
fondoger 2 years ago committed by GitHub
parent cddf3875cf
commit 5756627904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,19 +30,21 @@ Future {{pathToFuncName .Path}}( {{if ne .Method "get"}}{{with .RequestType}}{{.
{{end}}` {{end}}`
const apiTemplateV2 = `import 'api.dart'; const apiTemplateV2 = `import 'api.dart';
import '../data/{{with .Info}}{{getBaseName .Title}}{{end}}.dart'; import '../data/{{with .Service}}{{.Name}}{{end}}.dart';
{{with .Service}} {{with .Service}}
/// {{.Name}} /// {{.Name}}
{{range .Routes}} {{range $i, $Route := .Routes}}
/// --{{.Path}}-- /// --{{.Path}}--
/// ///
/// request: {{with .RequestType}}{{.Name}}{{end}} /// request: {{with .RequestType}}{{.Name}}{{end}}
/// response: {{with .ResponseType}}{{.Name}}{{end}} /// response: {{with .ResponseType}}{{.Name}}{{end}}
Future {{pathToFuncName .Path}}( {{if ne .Method "get"}}{{with .RequestType}}{{.Name}} request,{{end}}{{end}} Future {{normalizeHandlerName .Handler}}(
{{if hasUrlPathParams $Route}}{{extractPositionalParamsFromPath $Route}},{{end}}
{{if ne .Method "get"}}{{with .RequestType}}{{.Name}} request,{{end}}{{end}}
{Function({{with .ResponseType}}{{.Name}}{{end}})? ok, {Function({{with .ResponseType}}{{.Name}}{{end}})? ok,
Function(String)? fail, Function(String)? fail,
Function? eventually}) async { Function? eventually}) async {
await api{{if eq .Method "get"}}Get{{else}}Post{{end}}('{{.Path}}',{{if ne .Method "get"}}request,{{end}} await api{{if eq .Method "get"}}Get{{else}}Post{{end}}({{makeDartRequestUrlPath $Route}},{{if ne .Method "get"}}request,{{end}}
ok: (data) { ok: (data) {
if (ok != null) ok({{with .ResponseType}}{{.Name}}.fromJson(data){{end}}); if (ok != null) ok({{with .ResponseType}}{{.Name}}.fromJson(data){{end}});
}, fail: fail, eventually: eventually); }, fail: fail, eventually: eventually);

@ -11,6 +11,18 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/api/util" "github.com/zeromicro/go-zero/tools/goctl/api/util"
) )
const (
formTagKey = "form"
pathTagKey = "path"
headerTagKey = "header"
)
func normalizeHandlerName(handlerName string) string {
handler := strings.Replace(handlerName, "Handler", "", 1)
handler = lowCamelCase(handler)
return handler
}
func lowCamelCase(s string) string { func lowCamelCase(s string) string {
if len(s) < 1 { if len(s) < 1 {
return "" return ""
@ -20,21 +32,6 @@ func lowCamelCase(s string) string {
return util.ToLower(s[:1]) + s[1:] return util.ToLower(s[:1]) + s[1:]
} }
func pathToFuncName(path string) string {
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
if !strings.HasPrefix(path, "/api") {
path = "/api" + path
}
path = strings.Replace(path, "/", "_", -1)
path = strings.Replace(path, "-", "_", -1)
camel := util.ToCamelCase(path)
return util.ToLower(camel[:1]) + camel[1:]
}
func getBaseName(str string) string { func getBaseName(str string) string {
return path.Base(str) return path.Base(str)
} }
@ -170,3 +167,40 @@ func primitiveType(tp string) (string, bool) {
return "", false return "", false
} }
func hasUrlPathParams(route spec.Route) bool {
ds, ok := route.RequestType.(spec.DefineStruct)
if !ok {
return false
}
return len(route.RequestTypeName()) > 0 && len(ds.GetTagMembers(pathTagKey)) > 0
}
func extractPositionalParamsFromPath(route spec.Route) string {
ds, ok := route.RequestType.(spec.DefineStruct)
if !ok {
return ""
}
var params []string
for _, member := range ds.GetTagMembers(pathTagKey) {
params = append(params, fmt.Sprintf("%s %s", member.Type.Name(), getPropertyFromMember(member)))
}
return strings.Join(params, ", ")
}
func makeDartRequestUrlPath(route spec.Route) string {
path := route.Path
ds, ok := route.RequestType.(spec.DefineStruct)
if !ok {
return path
}
for _, member := range ds.GetTagMembers(pathTagKey) {
path = strings.ReplaceAll(path, ":"+pathTagKey, "${"+getPropertyFromMember(member)+"}")
}
return `"` + path + `"`
}

@ -8,8 +8,11 @@ var funcMap = template.FuncMap{
"isDirectType": isDirectType, "isDirectType": isDirectType,
"isClassListType": isClassListType, "isClassListType": isClassListType,
"getCoreType": getCoreType, "getCoreType": getCoreType,
"pathToFuncName": pathToFuncName,
"lowCamelCase": lowCamelCase, "lowCamelCase": lowCamelCase,
"normalizeHandlerName": normalizeHandlerName,
"hasUrlPathParams": hasUrlPathParams,
"extractPositionalParamsFromPath": extractPositionalParamsFromPath,
"makeDartRequestUrlPath": makeDartRequestUrlPath,
} }
const ( const (

Loading…
Cancel
Save