github.com/pavlo67/common@v0.5.3/common/server_http/endpoints_prepare.go (about) 1 package server_http 2 3 import ( 4 "fmt" 5 "net/url" 6 "regexp" 7 "strings" 8 ) 9 10 // Config ----------------------------------------------------------------------------------- 11 12 func (c *Config) EP(endpointKey EndpointKey, params []string, createFullURL bool) (string, string, error) { 13 if c == nil { 14 return "", "", nil 15 } 16 17 ep, ok := c.EndpointsSettled[endpointKey] 18 if !ok { 19 return "", "", fmt.Errorf("no endpoint with key '%s'", endpointKey) 20 } 21 22 if len(ep.PathParams) != len(params) { 23 return "", "", fmt.Errorf("wrong params list (%#v) for endpoint (%s / %#v)", params, endpointKey, ep) 24 } 25 26 var urlStr string 27 if createFullURL { 28 urlStr = c.Host 29 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 30 urlStr += ":" + c.Port 31 } 32 } 33 urlStr += c.Prefix + ep.Path 34 35 for i, param := range params { 36 if param == "" { 37 return "", "", fmt.Errorf("empty param %d in list (%#v) for endpoint (%s / %#v)", i, params, endpointKey, ep) 38 } 39 urlStr += "/" + url.PathEscape(param) 40 } 41 42 return ep.Method, urlStr, nil 43 } 44 45 var rePathParam = regexp.MustCompile(":[^/]+") 46 47 func (ed EndpointDescription) PathTemplate(serverPath string) string { 48 if len(serverPath) == 0 || serverPath[0] != '/' { 49 serverPath = "/" + serverPath 50 } 51 52 if len(ed.PathParams) < 1 { 53 54 // TODO!!! be careful with serverPath like ".../*something" 55 // if serverPath[len(serverPath)-1] != '/' { 56 // serverPath += "/" 57 // } 58 return serverPath 59 60 } else if serverPath[len(serverPath)-1] == '/' { 61 serverPath = serverPath[:len(serverPath)-1] 62 } 63 var pathParams []string 64 for _, pp := range ed.PathParams { 65 if len(pp) > 0 && pp[0] == '*' { 66 pathParams = append(pathParams, pp) 67 } else { 68 pathParams = append(pathParams, ":"+pp) 69 } 70 71 } 72 73 return serverPath + "/" + strings.Join(pathParams, "/") 74 } 75 76 func (ed EndpointDescription) PathTemplateBraced(serverPath string) string { 77 if len(serverPath) == 0 || serverPath[0] != '/' { 78 serverPath = "/" + serverPath 79 } 80 81 if len(ed.PathParams) < 1 { 82 return serverPath 83 } 84 85 var pathParams []string 86 for _, pp := range ed.PathParams { 87 if len(pp) > 0 && pp[0] == '*' { 88 pathParams = append(pathParams, pp[1:]) 89 } else { 90 pathParams = append(pathParams, pp) 91 } 92 93 } 94 95 return serverPath + "/{" + strings.Join(ed.PathParams, "}/{") + "}" 96 } 97 98 //func (ep Endpoint) PathWithParams(params ...string) string { 99 // matches := rePathParam.FindAllStringSubmatchIndex(ep.Path, -1) 100 // 101 // numMatches := len(matches) 102 // if len(params) < numMatches { 103 // numMatches = len(params) 104 // } 105 // 106 // path := ep.Path 107 // for nm := numMatches - 1; nm >= 0; nm-- { 108 // path = path[:matches[nm][0]] + url.PathEscape(strings.ReplaceTags(params[nm], "/", "%2F", -1)) + path[matches[nm][1]:] 109 // } 110 // 111 // return path 112 //} 113 114 // this trick allows to prevent run-time errors with wrong endpoint parameters number 115 // using CheckGet...() functions we move parameter number checks to initiation stage 116 117 type Get1 func(string) (string, error) 118 type Get2 func(string, string) (string, error) 119 type Get3 func(string, string, string) (string, error) 120 type Get4 func(string, string, string, string) (string, error) 121 122 func CheckGet0(c Config, endpointKey EndpointKey, createFullURL bool) (string, error) { 123 ep, ok := c.EndpointsSettled[endpointKey] 124 if !ok { 125 return "", fmt.Errorf("no endpoint with key '%s'", endpointKey) 126 } 127 128 if strings.ToUpper(ep.Method) != "GET" { 129 return "", fmt.Errorf("wrong endpoint.Method with key '%s': %#v", endpointKey, ep) 130 } 131 132 var urlStr string 133 if createFullURL { 134 urlStr = c.Host 135 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 136 urlStr += ":" + c.Port 137 } 138 } 139 urlStr += c.Prefix + ep.Path 140 141 return urlStr, nil 142 } 143 144 func CheckGet1(c Config, endpointKey EndpointKey, createFullURL bool) (Get1, error) { 145 ep, ok := c.EndpointsSettled[endpointKey] 146 if !ok { 147 return nil, fmt.Errorf("no endpoint with key '%s'", endpointKey) 148 } 149 150 var urlStr string 151 if createFullURL { 152 urlStr = c.Host 153 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 154 urlStr += ":" + c.Port 155 } 156 } 157 urlStr += c.Prefix + ep.Path 158 159 if strings.ToUpper(ep.Method) != "GET" { 160 return nil, fmt.Errorf("wrong endpoint.Method with key '%s': %#v", endpointKey, ep) 161 } 162 163 return func(p1 string) (string, error) { 164 p1 = strings.TrimSpace(p1) 165 if p1 == "" { 166 return "", fmt.Errorf("empty param %s for endpoint (%s / %#v)", p1, endpointKey, ep) 167 } 168 urlStr += "/" + url.PathEscape(p1) 169 return urlStr, nil 170 }, nil 171 } 172 173 func CheckGet2(c Config, endpointKey EndpointKey, createFullURL bool) (Get2, error) { 174 ep, ok := c.EndpointsSettled[endpointKey] 175 if !ok { 176 return nil, fmt.Errorf("no endpoint with key '%s'", endpointKey) 177 } 178 179 var urlStr string 180 if createFullURL { 181 urlStr = c.Host 182 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 183 urlStr += ":" + c.Port 184 } 185 } 186 urlStr += c.Prefix + ep.Path 187 188 if strings.ToUpper(ep.Method) != "GET" { 189 return nil, fmt.Errorf("wrong endpoint.Method with key '%s': %#v", endpointKey, ep) 190 } 191 192 return func(p1, p2 string) (string, error) { 193 params := [2]string{p1, p2} 194 for i, param := range params { 195 param = strings.TrimSpace(param) 196 if param == "" { 197 return "", fmt.Errorf("empty param %d in list (%#v) for endpoint (%s / %#v)", i, params, endpointKey, ep) 198 } 199 urlStr += "/" + url.PathEscape(param) 200 } 201 return urlStr, nil 202 }, nil 203 } 204 205 func CheckGet3(c Config, endpointKey EndpointKey, createFullURL bool) (Get3, error) { 206 ep, ok := c.EndpointsSettled[endpointKey] 207 if !ok { 208 return nil, fmt.Errorf("no endpoint with key '%s'", endpointKey) 209 } 210 211 var urlStr string 212 if createFullURL { 213 urlStr = c.Host 214 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 215 urlStr += ":" + c.Port 216 } 217 } 218 urlStr += c.Prefix + ep.Path 219 220 if strings.ToUpper(ep.Method) != "GET" { 221 return nil, fmt.Errorf("wrong endpoint.Method with key '%s': %#v", endpointKey, ep) 222 } 223 224 return func(p1, p2, p3 string) (string, error) { 225 params := [3]string{p1, p2, p3} 226 for i, param := range params { 227 param = strings.TrimSpace(param) 228 if param == "" { 229 return "", fmt.Errorf("empty param %d in list (%#v) for endpoint (%s / %#v)", i, params, endpointKey, ep) 230 } 231 urlStr += "/" + url.PathEscape(param) 232 } 233 return urlStr, nil 234 }, nil 235 } 236 237 func CheckGet4(c Config, endpointKey EndpointKey, createFullURL bool) (Get4, error) { 238 ep, ok := c.EndpointsSettled[endpointKey] 239 if !ok { 240 return nil, fmt.Errorf("no endpoint with key '%s'", endpointKey) 241 } 242 243 var urlStr string 244 if createFullURL { 245 urlStr = c.Host 246 if c.Port = strings.TrimSpace(c.Port); c.Port != "" { 247 urlStr += ":" + c.Port 248 } 249 } 250 urlStr += c.Prefix + ep.Path 251 252 if strings.ToUpper(ep.Method) != "GET" { 253 return nil, fmt.Errorf("wrong endpoint.Method with key '%s': %#v", endpointKey, ep) 254 } 255 256 return func(p1, p2, p3, p4 string) (string, error) { 257 params := [4]string{p1, p2, p3} 258 for i, param := range params { 259 param = strings.TrimSpace(param) 260 if param == "" { 261 return "", fmt.Errorf("empty param %d in list (%#v) for endpoint (%s / %#v)", i, params, endpointKey, ep) 262 } 263 urlStr += "/" + url.PathEscape(param) 264 } 265 return urlStr, nil 266 }, nil 267 }