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  }