buildBodyTypes traverses the design and builds the JSON schemas that represent the request and response bodies of each endpoint. The algorithm also computes a good unique name for the different types making sure that two types that are actually identical share the same name. This is to handle proper
(api *expr.APIExpr, types []expr.UserType, resultTypes []*expr.ResultTypeExpr)
| 62 | // |
| 63 | // NOTE: entries are nil when the corresponding type is Empty. |
| 64 | func buildBodyTypes(api *expr.APIExpr, types []expr.UserType, resultTypes []*expr.ResultTypeExpr) (map[string]map[string]*EndpointBodies, map[string]*openapi.Schema) { |
| 65 | bodies := make(map[string]map[string]*EndpointBodies) |
| 66 | sf := newSchemafier(api.ExampleGenerator) |
| 67 | |
| 68 | // Generates the types referenced from the endpoints. |
| 69 | for _, t := range types { |
| 70 | if !mustGenerateType(t.Attribute().Meta) { |
| 71 | continue |
| 72 | } |
| 73 | sf.schemafy(&expr.AttributeExpr{Type: t}) |
| 74 | } |
| 75 | for _, t := range resultTypes { |
| 76 | if !mustGenerateType(t.Attribute().Meta) { |
| 77 | continue |
| 78 | } |
| 79 | sf.schemafy(&expr.AttributeExpr{Type: t}) |
| 80 | } |
| 81 | |
| 82 | for _, s := range api.HTTP.Services { |
| 83 | if !openapi.MustGenerate(s.Meta) || !openapi.MustGenerate(s.ServiceExpr.Meta) { |
| 84 | continue |
| 85 | } |
| 86 | |
| 87 | sbodies := make(map[string]*EndpointBodies, len(s.HTTPEndpoints)) |
| 88 | for _, e := range s.HTTPEndpoints { |
| 89 | if !openapi.MustGenerate(e.Meta) || !openapi.MustGenerate(e.MethodExpr.Meta) { |
| 90 | continue |
| 91 | } |
| 92 | |
| 93 | req := sf.schemafy(e.Body) |
| 94 | if e.StreamingBody != nil { |
| 95 | sreq := sf.schemafy(e.StreamingBody) |
| 96 | var note string |
| 97 | if sreq.Ref != "" { |
| 98 | note = sreq.Ref |
| 99 | } else { |
| 100 | note = string(sreq.Type) |
| 101 | } |
| 102 | if req == nil { |
| 103 | req = sreq |
| 104 | if req.Description != "" { |
| 105 | req.Description += "\n" |
| 106 | } |
| 107 | req.Description += "Streaming body." |
| 108 | } else { |
| 109 | if req.Description != "" { |
| 110 | req.Description += "\n" |
| 111 | } |
| 112 | req.Description += fmt.Sprintf("Streaming body: %s", note) |
| 113 | } |
| 114 | } |
| 115 | res := make(map[int][]*openapi.Schema) |
| 116 | resps := e.Responses |
| 117 | for _, er := range e.HTTPErrors { |
| 118 | resps = append(resps, er.Response) |
| 119 | } |
| 120 | for _, resp := range resps { |
| 121 | var view string |