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  }