Example #1
0
File: api.go Project: cw2018/goa
// BasePath defines the API base path, i.e. the common path prefix to all the API actions.
// The path may define wildcards (see Routing for a description of the wildcard syntax).
// The corresponding parameters must be described using BaseParams.
func BasePath(val string) {
	if a, ok := apiDefinition(false); ok {
		a.BasePath = val
	} else if r, ok := resourceDefinition(true); ok {
		r.BasePath = val
		awcs := design.ExtractWildcards(design.Design.BasePath)
		wcs := design.ExtractWildcards(val)
		for _, awc := range awcs {
			for _, wc := range wcs {
				if awc == wc {
					ReportError(`duplicate wildcard "%s" in API and resource base paths`, wc)
				}
			}
		}
	}
}
Example #2
0
File: runner.go Project: goist/goa
// finalizeResource makes the final pass at the resource DSL. This is needed so that the order
// of DSL function calls is irrelevant. For example a resource response may be defined after an
// action refers to it.
func finalizeResource(r *design.ResourceDefinition) {
	r.IterateActions(func(a *design.ActionDefinition) error {
		// 1. Merge response definitions
		for name, resp := range a.Responses {
			if pr, ok := a.Parent.Responses[name]; ok {
				resp.Merge(pr)
			}
			if ar, ok := design.Design.Responses[name]; ok {
				resp.Merge(ar)
			}
			if dr, ok := design.Design.DefaultResponses[name]; ok {
				resp.Merge(dr)
			}
		}
		// 2. Create implicit action parameters for path wildcards that dont' have one
		for _, r := range a.Routes {
			design.Design.IterateVersions(func(ver *design.APIVersionDefinition) error {
				wcs := design.ExtractWildcards(r.FullPath(ver))
				for _, wc := range wcs {
					found := false
					var o design.Object
					if all := a.AllParams(); all != nil {
						o = all.Type.ToObject()
					} else {
						o = design.Object{}
						a.Params = &design.AttributeDefinition{Type: o}
					}
					for n := range o {
						if n == wc {
							found = true
							break
						}
					}
					if !found {
						o[wc] = &design.AttributeDefinition{Type: design.String}
					}
				}
				return nil
			})
		}
		// 3. Compute QueryParams from Params
		if params := a.Params; params != nil {
			queryParams := params.Dup()
			design.Design.IterateVersions(func(ver *design.APIVersionDefinition) error {
				for _, route := range a.Routes {
					pnames := route.Params(ver)
					for _, pname := range pnames {
						delete(queryParams.Type.ToObject(), pname)
					}
				}
				return nil
			})
			// (note: we may end up with required attribute names that don't correspond
			// to actual attributes cos' we just deleted them but that's probably OK.)
			a.QueryParams = queryParams
		}
		return nil
	})
}
Example #3
0
File: action.go Project: tylerb/goa
// Routing lists the action route. Each route is defined with a function named after the HTTP method.
// The route function takes the path as argument. Route paths may use wildcards as described in the
// [httprouter](https://godoc.org/github.com/julienschmidt/httprouter) package documentation. These
// wildcards define parameters using the `:name` or `*name` syntax where `:name` matches a path
// segment and `*name` is a catch-all that matches the path until the end.
func Routing(routes ...*design.RouteDefinition) {
	if a, ok := actionDefinition(true); ok {
		for _, r := range routes {
			rwcs := design.ExtractWildcards(a.Parent.FullPath())
			wcs := design.ExtractWildcards(r.Path)
			for _, rwc := range rwcs {
				for _, wc := range wcs {
					if rwc == wc {
						ReportError(`duplicate wildcard "%s" in resource base path "%s" and action route "%s"`,
							wc, a.Parent.FullPath(), r.Path)
					}
				}
			}
			r.Parent = a
			a.Routes = append(a.Routes, r)
		}
	}
}
Example #4
0
func paramsFromDefinition(params *design.AttributeDefinition, path string) ([]*Parameter, error) {
	if params == nil {
		return nil, nil
	}
	obj := params.Type.ToObject()
	if obj == nil {
		return nil, fmt.Errorf("invalid parameters definition, not an object")
	}
	res := make([]*Parameter, len(obj))
	i := 0
	wildcards := design.ExtractWildcards(path)
	obj.IterateAttributes(func(n string, at *design.AttributeDefinition) error {
		in := "query"
		required := params.IsRequired(n)
		for _, w := range wildcards {
			if n == w {
				in = "path"
				required = true
				break
			}
		}
		param := &Parameter{
			Name:        n,
			Default:     at.DefaultValue,
			Description: at.Description,
			Required:    required,
			In:          in,
			Type:        at.Type.Name(),
		}
		var items *Items
		if at.Type.IsArray() {
			items = itemsFromDefinition(at)
		}
		param.Items = items
		initValidations(at, param)
		res[i] = param
		i++
		return nil
	})
	return res, nil
}
Example #5
0
File: runner.go Project: harboe/goa
// finalizeResource makes the final pass at the resource DSL. This is needed so that the order
// of DSL function calls is irrelevant. For example a resource response may be defined after an
// action refers to it.
func finalizeResource(r *design.ResourceDefinition) {
	r.IterateActions(func(a *design.ActionDefinition) error {
		// 1. Merge response definitions
		for name, resp := range a.Responses {
			if pr, ok := a.Parent.Responses[name]; ok {
				resp.Merge(pr)
			}
			if ar, ok := design.Design.Responses[name]; ok {
				resp.Merge(ar)
			}
			if dr, ok := design.Design.DefaultResponses[name]; ok {
				resp.Merge(dr)
			}
		}
		// 2. Create implicit action parameters for path wildcards that dont' have one
		for _, r := range a.Routes {
			wcs := design.ExtractWildcards(r.FullPath())
			for _, wc := range wcs {
				found := false
				var o design.Object
				if a.Params != nil {
					o = a.Params.Type.ToObject()
				} else {
					o = design.Object{}
					a.Params = &design.AttributeDefinition{Type: o}
				}
				for n := range o {
					if n == wc {
						found = true
						break
					}
				}
				if !found {
					o[wc] = &design.AttributeDefinition{Type: design.String}
				}
			}
		}
		return nil
	})
}