github.com/annwntech/go-micro/v2@v2.9.5/api/resolver/vpath/vpath.go (about) 1 // Package vpath resolves using http path and recognised versioned urls 2 package vpath 3 4 import ( 5 "errors" 6 "net/http" 7 "regexp" 8 "strings" 9 10 "github.com/annwntech/go-micro/v2/api/resolver" 11 ) 12 13 func NewResolver(opts ...resolver.Option) resolver.Resolver { 14 return &Resolver{opts: resolver.NewOptions(opts...)} 15 } 16 17 type Resolver struct { 18 opts resolver.Options 19 } 20 21 var ( 22 re = regexp.MustCompile("^v[0-9]+$") 23 ) 24 25 func (r *Resolver) Resolve(req *http.Request, opts ...resolver.ResolveOption) (*resolver.Endpoint, error) { 26 // parse options 27 options := resolver.NewResolveOptions(opts...) 28 if req.URL.Path == "/" { 29 return nil, errors.New("unknown name") 30 } 31 32 parts := strings.Split(req.URL.Path[1:], "/") 33 if len(parts) == 1 { 34 return &resolver.Endpoint{ 35 Name: r.withNamespace(req, parts...), 36 Host: req.Host, 37 Method: req.Method, 38 Path: req.URL.Path, 39 Domain: options.Domain, 40 }, nil 41 } 42 43 // /v1/foo 44 if re.MatchString(parts[0]) { 45 return &resolver.Endpoint{ 46 Name: r.withNamespace(req, parts[0:2]...), 47 Host: req.Host, 48 Method: req.Method, 49 Path: req.URL.Path, 50 Domain: options.Domain, 51 }, nil 52 } 53 54 return &resolver.Endpoint{ 55 Name: r.withNamespace(req, parts[0]), 56 Host: req.Host, 57 Method: req.Method, 58 Path: req.URL.Path, 59 Domain: options.Domain, 60 }, nil 61 } 62 63 func (r *Resolver) String() string { 64 return "path" 65 } 66 67 func (r *Resolver) withNamespace(req *http.Request, parts ...string) string { 68 ns := r.opts.Namespace(req) 69 if len(ns) == 0 { 70 return strings.Join(parts, ".") 71 } 72 73 return strings.Join(append([]string{ns}, parts...), ".") 74 }