| 504 | } |
| 505 | |
| 506 | func buildPathFromExpr(s *V2, root *expr.RootExpr, h *expr.HostExpr, route *expr.RouteExpr, basePath string) { |
| 507 | endpoint := route.Endpoint |
| 508 | |
| 509 | tagNames := openapi.TagNamesFromExpr(endpoint.Meta) |
| 510 | if len(tagNames) == 0 { |
| 511 | // By default tag with service name |
| 512 | tagNames = []string{route.Endpoint.Service.Name()} |
| 513 | } |
| 514 | for _, key := range route.FullPaths() { |
| 515 | // Remove any wildcards that is defined in path as a workaround to |
| 516 | // https://github.com/OAI/OpenAPI-Specification/issues/291 |
| 517 | key = expr.HTTPWildcardRegex.ReplaceAllString(key, "/{$1}") |
| 518 | params := paramsFromExpr(endpoint, endpoint.Params, key) |
| 519 | params = append(params, paramsFromHeaders(endpoint)...) |
| 520 | var produces []string |
| 521 | |
| 522 | responses := make(map[string]*Response, len(endpoint.Responses)) |
| 523 | for _, r := range endpoint.Responses { |
| 524 | if endpoint.MethodExpr.IsStreaming() { |
| 525 | // A streaming endpoint allows at most one successful response |
| 526 | // definition. So it is okay to change the first successful |
| 527 | // response to a HTTP 101 response for openapi docs. |
| 528 | if _, ok := responses[strconv.Itoa(expr.StatusSwitchingProtocols)]; !ok { |
| 529 | r = r.Dup() |
| 530 | r.StatusCode = expr.StatusSwitchingProtocols |
| 531 | } |
| 532 | } |
| 533 | resp := responseSpecFromExpr(s, root, r, endpoint.Service.Name()) |
| 534 | responses[strconv.Itoa(r.StatusCode)] = resp |
| 535 | if r.ContentType != "" { |
| 536 | foundCT := slices.Contains(produces, r.ContentType) |
| 537 | if !foundCT { |
| 538 | produces = append(produces, r.ContentType) |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | for _, er := range endpoint.HTTPErrors { |
| 543 | resp := responseSpecFromExpr(s, root, er.Response, endpoint.Service.Name()) |
| 544 | responses[strconv.Itoa(er.Response.StatusCode)] = resp |
| 545 | } |
| 546 | |
| 547 | var consumes []string |
| 548 | if endpoint.MultipartRequest { |
| 549 | consumes = []string{"multipart/form-data"} |
| 550 | } |
| 551 | |
| 552 | if endpoint.Body.Type != expr.Empty { |
| 553 | in := "body" |
| 554 | if endpoint.MultipartRequest { |
| 555 | in = "formData" |
| 556 | } |
| 557 | pp := &Parameter{ |
| 558 | Name: endpoint.Body.Type.Name(), |
| 559 | In: in, |
| 560 | Description: endpoint.Body.Description, |
| 561 | Required: true, |
| 562 | Schema: openapi.AttributeTypeSchemaWithPrefix(root.API, endpoint.Body, codegen.Goify(endpoint.Service.Name(), true)), |
| 563 | } |