github.com/annwntech/go-micro/v2@v2.9.5/resolver/api/route.go (about) 1 package api 2 3 import ( 4 "path" 5 "regexp" 6 "strings" 7 ) 8 9 var ( 10 proxyRe = regexp.MustCompile("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$") 11 versionRe = regexp.MustCompilePOSIX("^v[0-9]+$") 12 ) 13 14 // Translates /foo/bar/zool into api service go.micro.api.foo method Bar.Zool 15 // Translates /foo/bar into api service go.micro.api.foo method Foo.Bar 16 func apiRoute(p string) (string, string) { 17 p = path.Clean(p) 18 p = strings.TrimPrefix(p, "/") 19 parts := strings.Split(p, "/") 20 21 // if we have 1 part assume name Name.Call 22 if len(parts) == 1 && len(parts[0]) > 0 { 23 return parts[0], methodName(append(parts, "Call")) 24 } 25 26 // If we've got two or less parts 27 // Use first part as service 28 // Use all parts as method 29 if len(parts) <= 2 { 30 name := parts[0] 31 return name, methodName(parts) 32 } 33 34 // Treat /v[0-9]+ as versioning where we have 3 parts 35 // /v1/foo/bar => service: v1.foo method: Foo.bar 36 if len(parts) == 3 && versionRe.Match([]byte(parts[0])) { 37 name := strings.Join(parts[:len(parts)-1], ".") 38 return name, methodName(parts[len(parts)-2:]) 39 } 40 // Treat /v[0-9]+ as versioning where we have 3 parts 41 // /v1/foo/bar => service: v1.foo method: Foo.bar 42 // check if it has one more part as identifier associated with request 43 if len(parts) == 4 && versionRe.Match([]byte(parts[0])) { 44 name := strings.Join(parts[:len(parts)-1], ".") 45 return name, methodName(parts[len(parts)-3 : len(parts)-1]) 46 } 47 48 // Service is everything minus last two parts 49 // Method is the last two parts 50 name := strings.Join(parts[:len(parts)-2], ".") 51 return name, methodName(parts[len(parts)-2:]) 52 } 53 54 func proxyRoute(p string) string { 55 parts := strings.Split(p, "/") 56 if len(parts) < 2 { 57 return "" 58 } 59 60 var service string 61 var alias string 62 63 // /[service]/methods 64 if len(parts) > 2 { 65 // /v1/[service] 66 if versionRe.MatchString(parts[1]) { 67 service = parts[1] + "." + parts[2] 68 alias = parts[2] 69 } else { 70 service = parts[1] 71 alias = parts[1] 72 } 73 // /[service] 74 } else { 75 service = parts[1] 76 alias = parts[1] 77 } 78 79 // check service name is valid 80 if !proxyRe.MatchString(alias) { 81 return "" 82 } 83 84 return service 85 } 86 87 func methodName(parts []string) string { 88 for i, part := range parts { 89 parts[i] = toCamel(part) 90 } 91 92 return strings.Join(parts, ".") 93 } 94 95 func toCamel(s string) string { 96 words := strings.Split(s, "-") 97 var out string 98 for _, word := range words { 99 out += strings.Title(word) 100 } 101 return out 102 }