MCPcopy Create free account
hub / github.com/goadesign/goa / Validate

Method Validate

expr/http_endpoint.go:1001–1061  ·  view source on GitHub ↗

Validate validates a route expression by ensuring that the route parameters can be inferred from the method payload and there is no duplicate parameters in an absolute route.

()

Source from the content-addressed store, hash-verified

999// can be inferred from the method payload and there is no duplicate parameters
1000// in an absolute route.
1001func (r *RouteExpr) Validate() *eval.ValidationErrors {
1002 verr := new(eval.ValidationErrors)
1003
1004 // Make sure route params are defined in the method payload
1005 if rparams := r.Params(); len(rparams) > 0 {
1006 if r.Endpoint.MethodExpr.Payload == nil {
1007 verr.Add(r, "Route parameters are defined, but method payload is not defined.")
1008 } else {
1009 switch r.Endpoint.MethodExpr.Payload.Type.(type) {
1010 case *Map:
1011 verr.Add(r, "Route parameters are defined, but method payload is a map. Method payload must be a primitive or an object.")
1012 case *Object, UserType:
1013 for _, p := range rparams {
1014 if r.Endpoint.MethodExpr.Payload.Find(p) == nil {
1015 verr.Add(r, "Route param %q not found in method payload", p)
1016 }
1017 }
1018 }
1019 if len(rparams) > 1 && IsPrimitive(r.Endpoint.MethodExpr.Payload.Type) {
1020 verr.Add(r, "Multiple route parameters are defined, but method payload is a primitive. Only one router parameter can be defined if payload is primitive.")
1021 }
1022 }
1023 }
1024
1025 // Make sure there's no duplicate params in absolute route
1026 paths := r.FullPaths()
1027 for _, path := range paths {
1028 matches := HTTPWildcardRegex.FindAllStringSubmatch(path, -1)
1029 wcs := make(map[string]struct{}, len(matches))
1030 for _, match := range matches {
1031 if _, ok := wcs[match[1]]; ok {
1032 verr.Add(r, "Wildcard %q appears multiple times in full path %q", match[1], path)
1033 }
1034 wcs[match[1]] = struct{}{}
1035 }
1036 }
1037
1038 // For WebSocket streaming endpoints, only GET is supported
1039 // SSE endpoints can use both GET and POST (JSON-RPC SSE uses POST)
1040 if r.Endpoint.MethodExpr.IsStreaming() && len(r.Endpoint.Responses) > 0 && r.Endpoint.SSE == nil {
1041 if r.Method != "GET" {
1042 verr.Add(r, "WebSocket endpoint supports only \"GET\" method. Got %q.", r.Method)
1043 }
1044 }
1045
1046 // HEAD method must not return a response body as per RFC 2616 section 9.4
1047 if r.Method == "HEAD" {
1048 disallowBody := func(resp *HTTPResponseExpr) {
1049 if httpResponseBody(r.Endpoint, resp).Type != Empty {
1050 verr.Add(r, "HTTP status %d: Response body defined for HEAD method which does not allow response body.", resp.StatusCode)
1051 }
1052 }
1053 for _, resp := range r.Endpoint.Responses {
1054 disallowBody(resp)
1055 }
1056 for _, e := range r.Endpoint.HTTPErrors {
1057 disallowBody(e.Response)
1058 }

Callers

nothing calls this directly

Calls 7

ParamsMethod · 0.95
FullPathsMethod · 0.95
IsPrimitiveFunction · 0.85
httpResponseBodyFunction · 0.85
AddMethod · 0.80
FindMethod · 0.80
IsStreamingMethod · 0.45

Tested by

no test coverage detected