Finalize is run post DSL execution. It merges response definitions, creates implicit endpoint parameters and initializes querystring parameters. It also flattens the error responses and makes sure the error types are all user types so that the response encoding code can properly use the type to infe
()
| 744 | // types so that the response encoding code can properly use the type to infer |
| 745 | // the response that it needs to build. |
| 746 | func (e *HTTPEndpointExpr) Finalize() { |
| 747 | // For JSON-RPC WebSocket endpoints with server streaming and non-streaming payload, |
| 748 | // move the payload to streaming payload. This is because the payload is sent as |
| 749 | // JSON-RPC messages after the WebSocket connection is established, making it |
| 750 | // effectively a streaming payload from the transport perspective. |
| 751 | if _, isJSONRPC := e.MethodExpr.Meta["jsonrpc"]; isJSONRPC && e.MethodExpr.Stream == ServerStreamKind && e.SSE == nil { |
| 752 | if e.MethodExpr.Payload.Type != Empty && e.MethodExpr.StreamingPayload.Type == Empty { |
| 753 | // Move payload to streaming payload |
| 754 | e.MethodExpr.StreamingPayload = e.MethodExpr.Payload |
| 755 | e.MethodExpr.Payload = &AttributeExpr{Type: Empty} |
| 756 | // Change stream kind to bidirectional since we now have both streaming payload and result |
| 757 | e.MethodExpr.Stream = BidirectionalStreamKind |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | // Compute security scheme attribute name and corresponding HTTP location |
| 762 | requirements := EffectiveSecurityRequirements(e.MethodExpr.Requirements) |
| 763 | if reqLen := len(requirements); reqLen > 0 { |
| 764 | e.Requirements = make([]*SecurityExpr, 0, reqLen) |
| 765 | for _, req := range requirements { |
| 766 | dupReq := DupRequirement(req) |
| 767 | for _, sch := range dupReq.Schemes { |
| 768 | var field string |
| 769 | switch sch.Kind { |
| 770 | case NoKind: |
| 771 | continue |
| 772 | case BasicAuthKind: |
| 773 | sch.In = "header" |
| 774 | sch.Name = "Authorization" |
| 775 | continue |
| 776 | case APIKeyKind: |
| 777 | field = TaggedAttribute(e.MethodExpr.Payload, "security:apikey:"+sch.SchemeName) |
| 778 | case BearerKind: |
| 779 | field = TaggedAttribute(e.MethodExpr.Payload, "security:bearer") |
| 780 | case JWTKind: |
| 781 | field = TaggedAttribute(e.MethodExpr.Payload, "security:token") |
| 782 | case OAuth2Kind: |
| 783 | field = TaggedAttribute(e.MethodExpr.Payload, "security:accesstoken") |
| 784 | } |
| 785 | sch.Name, sch.In = findKey(e, field) |
| 786 | if sch.Name == "" { |
| 787 | // Initialize Authorization header implicitly defined via |
| 788 | // security DSL if mapping isn't explicit. |
| 789 | sch.Name = "Authorization" |
| 790 | attr := e.MethodExpr.Payload.Find(field) |
| 791 | e.Headers.Type.(*Object).Set(field, attr) |
| 792 | e.Headers.Map(sch.Name, field) |
| 793 | if e.MethodExpr.Payload.IsRequired(field) { |
| 794 | if e.Headers.Validation == nil { |
| 795 | e.Headers.Validation = &ValidationExpr{} |
| 796 | } |
| 797 | e.Headers.Validation.AddRequired(field) |
| 798 | } |
| 799 | } |
| 800 | } |
| 801 | e.Requirements = append(e.Requirements, dupReq) |
| 802 | } |
| 803 | } |
nothing calls this directly
no test coverage detected