github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/client/gen/v3/to_client.go (about)

     1  package v3
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"strings"
     7  
     8  	"github.com/morlay/oas"
     9  
    10  	"github.com/johnnyeven/libtools/codegen"
    11  	"github.com/johnnyeven/libtools/courier/client/gen/common"
    12  	"github.com/johnnyeven/libtools/courier/httpx"
    13  	"github.com/johnnyeven/libtools/courier/swagger/gen"
    14  	"github.com/johnnyeven/libtools/courier/transport_http/transform"
    15  )
    16  
    17  func ToClient(baseClient string, serviceName string, openAPI *oas.OpenAPI) string {
    18  	clientSet := common.NewClientSet(baseClient, serviceName)
    19  
    20  	for path, pathItem := range openAPI.Paths.Paths {
    21  		for method := range pathItem.Operations.Operations {
    22  			clientSet.AddOp(OpenAPIOperationFrom(serviceName, strings.ToUpper(string(method)), path, pathItem.Operations.Operations[method], openAPI.Components))
    23  		}
    24  	}
    25  
    26  	return clientSet.String()
    27  }
    28  
    29  func OpenAPIOperationFrom(serviceName string, method string, path string, operation *oas.Operation, components oas.Components) *OpenAPIOperation {
    30  	return &OpenAPIOperation{
    31  		serviceName: serviceName,
    32  		method:      method,
    33  		path:        path,
    34  		Operation:   operation,
    35  		components:  components,
    36  	}
    37  }
    38  
    39  type OpenAPIOperation struct {
    40  	serviceName string
    41  	method      string
    42  	path        string
    43  	*oas.Operation
    44  	components oas.Components
    45  }
    46  
    47  var _ interface {
    48  	common.Op
    49  } = (*OpenAPIOperation)(nil)
    50  
    51  func (op *OpenAPIOperation) Method() string {
    52  	return op.method
    53  }
    54  
    55  func (op *OpenAPIOperation) ID() string {
    56  	return op.Operation.OperationId
    57  }
    58  
    59  func (op *OpenAPIOperation) Path() string {
    60  	return common.PathFromSwaggerPath(op.path)
    61  }
    62  
    63  func (op *OpenAPIOperation) HasRequest() bool {
    64  	return len(op.Operation.Parameters) > 0 || op.RequestBody != nil
    65  }
    66  
    67  func (op *OpenAPIOperation) WriteReqType(w io.Writer, importer *codegen.Importer) {
    68  	io.WriteString(w, `struct {
    69  `)
    70  
    71  	for _, parameter := range op.Parameters {
    72  		schema := mayComposedFieldSchema(parameter.Schema)
    73  
    74  		fieldName := codegen.ToUpperCamelCase(parameter.Name)
    75  		if parameter.Extensions[gen.XField] != nil {
    76  			fieldName = parameter.Extensions[gen.XField].(string)
    77  		}
    78  
    79  		field := common.NewField(fieldName)
    80  		field.AddTag("in", string(parameter.In))
    81  		field.AddTag("name", parameter.Name)
    82  
    83  		field.Comment = parameter.Description
    84  
    85  		if parameter.Extensions[gen.XTagValidate] != nil {
    86  			field.AddTag("validate", fmt.Sprintf("%s", parameter.Extensions[gen.XTagValidate]))
    87  		}
    88  
    89  		if !parameter.Required {
    90  			if schema != nil {
    91  				d := fmt.Sprintf("%v", schema.Default)
    92  				if schema.Default != nil && d != "" {
    93  					field.AddTag("default", d)
    94  				}
    95  			}
    96  			field.AddTag("name", parameter.Name, "omitempty")
    97  		}
    98  
    99  		if schema != nil {
   100  			field.Type, _ = NewTypeGenerator(op.serviceName, importer).Type(schema)
   101  		}
   102  
   103  		io.WriteString(w, field.String())
   104  	}
   105  
   106  	if op.RequestBody != nil {
   107  		field := common.NewField("Body")
   108  		if jsonMedia, ok := op.RequestBody.Content[httpx.MIMEJSON]; ok && jsonMedia.Schema != nil {
   109  			field.Type, _ = NewTypeGenerator(op.serviceName, importer).Type(jsonMedia.Schema)
   110  			field.Comment = jsonMedia.Schema.Description
   111  			field.AddTag("in", "body")
   112  			field.AddTag("fmt", transform.GetContentTransformer(httpx.MIMEJSON).Key)
   113  		}
   114  		if formMedia, ok := op.RequestBody.Content[httpx.MIMEMultipartPOSTForm]; ok && formMedia.Schema != nil {
   115  			field.Type, _ = NewTypeGenerator(op.serviceName, importer).Type(formMedia.Schema)
   116  			field.Comment = formMedia.Schema.Description
   117  			field.AddTag("in", "formData,multipart")
   118  		}
   119  		if formMedia, ok := op.RequestBody.Content[httpx.MIMEPOSTForm]; ok && formMedia.Schema != nil {
   120  			field.Type, _ = NewTypeGenerator(op.serviceName, importer).Type(formMedia.Schema)
   121  			field.Comment = formMedia.Schema.Description
   122  			field.AddTag("in", "formData")
   123  		}
   124  		io.WriteString(w, field.String())
   125  	}
   126  
   127  	io.WriteString(w, `
   128  }
   129  `)
   130  }
   131  
   132  func (op *OpenAPIOperation) WriteRespBodyType(w io.Writer, importer *codegen.Importer) {
   133  	respBodySchema := op.respBodySchema()
   134  	if respBodySchema == nil {
   135  		io.WriteString(w, `[]byte`)
   136  		return
   137  	}
   138  	tpe, _ := NewTypeGenerator(op.serviceName, importer).Type(respBodySchema)
   139  	io.WriteString(w, tpe)
   140  }
   141  
   142  func (op *OpenAPIOperation) respBodySchema() (schema *oas.Schema) {
   143  	if op.Responses.Responses == nil {
   144  		return nil
   145  	}
   146  
   147  	for code, resp := range op.Responses.Responses {
   148  		if resp.Ref != "" && op.components.Responses != nil {
   149  			if presetResponse, ok := op.components.Responses[common.RefName(resp.Ref)]; ok {
   150  				resp = presetResponse
   151  			}
   152  		}
   153  
   154  		if code >= 200 && code < 300 {
   155  			if resp.Content[httpx.MIMEJSON] != nil {
   156  				schema = resp.Content[httpx.MIMEJSON].Schema
   157  				return
   158  			}
   159  		}
   160  	}
   161  
   162  	return
   163  }