metadata/action.go
func (a *Action) URL(vars []*PathVariable) (*ActionPath, error) {
	candidates := make([]*ActionPath, len(a.PathPatterns))
	allMissing := []string{}
	j := 0
	for _, p := range a.PathPatterns {
		path, names := p.Substitute(vars)
		if path == "" {
			allMissing = append(allMissing, names...)
		} else {
			candidates[j] = &ActionPath{path, p.HTTPMethod, len(names)}
			j++
		}
	}
	if j == 0 {
		return nil, fmt.Errorf("Missing variables to instantiate action URL, one or more of the following variables are needed: %s",
			strings.Join(allMissing, ", "))
	}
	candidates = candidates[:j]
	sort.Sort(ByWeight(candidates))
	return candidates[0], nil
}
func (a *Action) URL(vars []*PathVariable) (*ActionPath, error) {
	candidates := make([]*ActionPath, len(a.PathPatterns))
	allMissing := []string{}
	j := 0
	for _, p := range a.PathPatterns {
		path, names := p.Substitute(vars)
		if path == "" {
			allMissing = append(allMissing, names...)
		} else {
			candidates[j] = &ActionPath{path, p.HTTPMethod, len(names)}
			j++
		}
	}
	if j == 0 {
		return nil, fmt.Errorf("Missing variables to instantiate action URL, one or more of the following variables are needed: %s",
			strings.Join(allMissing, ", "))
	}
	candidates = candidates[:j]
	sort.Sort(ByWeight(candidates))
	return candidates[0], nil
}
// URL returns a URL to the action given a set of values that can be used to substitute the action
// paths pattern variables. This method tries to use a many variables as possible so that
// "the longest" path gets used. So if for example an action has the patterns "/instances/:id" and
// "/clouds/:cloud_id/instances/:id" and both the :cloud_id and :id variable values are given as
// parameter, the method returns a URL built from substituting the values of the later (longer) path.
// The method returns an error in case no path pattern can have all its variables subsituted.