github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/cmd/protoc-gen-openapi/converter/service.go (about) 1 package converter 2 3 import ( 4 "fmt" 5 6 "github.com/getkin/kin-openapi/openapi3" 7 "github.com/golang/protobuf/protoc-gen-go/descriptor" 8 "github.com/tickoalcantara12/micro/v3/service/logger" 9 ) 10 11 // Converts a proto "SERVICE" into an OpenAPI path: 12 func (c *Converter) convertServiceType(file *descriptor.FileDescriptorProto, curPkg *ProtoPackage, svc *descriptor.ServiceDescriptorProto) (map[string]*openapi3.PathItem, error) { 13 pathItems := make(map[string]*openapi3.PathItem) 14 15 // Add a path item for each method in the service: 16 for _, method := range svc.GetMethod() { 17 logger.Debugf("Processing method %s.%s()", svc.GetName(), method.GetName()) 18 19 // Figure out the URL path: 20 path := urlPath(c.microServiceName, svc.GetName(), method.GetName()) 21 22 // We need to reformat the request name to match what is produced by the message converter: 23 requestPayloadSchemaName := protoServiceName(*method.InputType) 24 25 // See if we can get the request paylod schema: 26 if _, ok := c.openAPISpec.Components.Schemas[requestPayloadSchemaName]; !ok { 27 logger.Warnf("Couldn't find request body payload (%s)", requestPayloadSchemaName) 28 continue 29 } 30 31 // Make a request body: 32 requestBodyName := requestBodyName(svc.GetName(), method.GetName()) 33 requestBody := &openapi3.RequestBodyRef{ 34 Value: &openapi3.RequestBody{ 35 Content: openapi3.Content{ 36 "application/json": &openapi3.MediaType{ 37 Schema: &openapi3.SchemaRef{ 38 Ref: messageSchemaPath(requestPayloadSchemaName), 39 }, 40 }, 41 }, 42 Description: requestBodyName, 43 }, 44 } 45 46 // Add it to the spec: 47 c.openAPISpec.Components.RequestBodies[requestBodyName] = requestBody 48 49 // We need to reformat the response name to match what is produced by the message converter: 50 responsePayloadSchemaName := protoServiceName(*method.OutputType) 51 52 // See if we can get the response paylod schema: 53 if _, ok := c.openAPISpec.Components.Schemas[responsePayloadSchemaName]; !ok { 54 logger.Warnf("Couldn't find response body payload (%s)", responsePayloadSchemaName) 55 continue 56 } 57 58 // Make a response body: 59 responseBodyName := responseBodyName(svc.GetName(), method.GetName()) 60 responseBody := &openapi3.ResponseRef{ 61 Value: &openapi3.Response{ 62 Content: openapi3.Content{ 63 "application/json": &openapi3.MediaType{ 64 Schema: &openapi3.SchemaRef{ 65 Ref: messageSchemaPath(responsePayloadSchemaName), 66 }, 67 }, 68 }, 69 Description: &responseBodyName, 70 }, 71 } 72 73 // Add it to the spec: 74 c.openAPISpec.Components.Responses[responseBodyName] = responseBody 75 76 // Prepare a path item based on these payloads: 77 pathItem := &openapi3.PathItem{ 78 Parameters: openapi3.Parameters{ 79 { 80 Value: &openapi3.Parameter{ 81 In: "header", 82 Name: "Micro-Namespace", 83 Required: true, 84 Schema: &openapi3.SchemaRef{ 85 Value: &openapi3.Schema{ 86 Type: "string", 87 Default: "micro", 88 }, 89 }, 90 }, 91 }, 92 }, 93 Post: &openapi3.Operation{ 94 RequestBody: &openapi3.RequestBodyRef{ 95 Ref: requestBodySchemaPath(requestBodyName), 96 }, 97 Responses: openapi3.Responses{ 98 "default": &openapi3.ResponseRef{ 99 Ref: responseBodySchemaPath("MicroAPIError"), 100 }, 101 "200": &openapi3.ResponseRef{ 102 Ref: responseBodySchemaPath(responseBodyName), 103 }, 104 }, 105 Security: &openapi3.SecurityRequirements{ 106 { 107 "MicroAPIToken": []string{}, 108 }, 109 }, 110 Summary: fmt.Sprintf("%s.%s(%s)", svc.GetName(), method.GetName(), requestPayloadSchemaName), 111 }, 112 } 113 114 // check if it's a streaming response 115 if method.GetServerStreaming() { 116 pathItem.Post.Responses["stream"] = &openapi3.ResponseRef{ 117 Ref: responseBodySchemaPath(responseBodyName), 118 } 119 } 120 121 // TODO: check for method.GetClientStreaming() 122 123 // Generate a description from src comments (if available) 124 if src := c.sourceInfo.GetService(svc); src != nil { 125 pathItem.Description = formatDescription(src) 126 } 127 128 pathItems[path] = pathItem 129 } 130 131 return pathItems, nil 132 }