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

     1  package v2
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"strings"
     7  
     8  	"github.com/go-openapi/spec"
     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  )
    15  
    16  func ToClient(baseClient string, serviceName string, swagger *spec.Swagger) string {
    17  	clientSet := common.NewClientSet(baseClient, serviceName)
    18  
    19  	for path, pathItem := range swagger.Paths.Paths {
    20  		if pathItem.PathItemProps.Get != nil {
    21  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "GET", path, pathItem.PathItemProps.Get, swagger.Responses))
    22  		}
    23  		if pathItem.PathItemProps.Post != nil {
    24  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "POST", path, pathItem.PathItemProps.Post, swagger.Responses))
    25  		}
    26  		if pathItem.PathItemProps.Put != nil {
    27  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "PUT", path, pathItem.PathItemProps.Put, swagger.Responses))
    28  		}
    29  		if pathItem.PathItemProps.Delete != nil {
    30  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "DELETE", path, pathItem.PathItemProps.Delete, swagger.Responses))
    31  		}
    32  		if pathItem.PathItemProps.Head != nil {
    33  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "HEAD", path, pathItem.PathItemProps.Head, swagger.Responses))
    34  		}
    35  		if pathItem.PathItemProps.Patch != nil {
    36  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "PATCH", path, pathItem.PathItemProps.Patch, swagger.Responses))
    37  		}
    38  		if pathItem.PathItemProps.Options != nil {
    39  			clientSet.AddOp(SwaggerOperationFrom(serviceName, "OPTIONS", path, pathItem.PathItemProps.Options, swagger.Responses))
    40  		}
    41  	}
    42  
    43  	return clientSet.String()
    44  }
    45  
    46  func SwaggerOperationFrom(serviceName string, method string, path string, operation *spec.Operation, responses map[string]spec.Response) *SwaggerOperation {
    47  	return &SwaggerOperation{
    48  		serviceName: serviceName,
    49  		method:      method,
    50  		path:        path,
    51  		Operation:   operation,
    52  		responses:   responses,
    53  	}
    54  }
    55  
    56  type SwaggerOperation struct {
    57  	serviceName string
    58  	method      string
    59  	path        string
    60  	*spec.Operation
    61  	responses map[string]spec.Response
    62  }
    63  
    64  var _ interface {
    65  	common.Op
    66  } = (*SwaggerOperation)(nil)
    67  
    68  func (op *SwaggerOperation) Method() string {
    69  	return op.method
    70  }
    71  
    72  func (op *SwaggerOperation) ID() string {
    73  	return op.Operation.ID
    74  }
    75  
    76  func (op *SwaggerOperation) Path() string {
    77  	return common.PathFromSwaggerPath(op.path)
    78  }
    79  
    80  func (op *SwaggerOperation) HasRequest() bool {
    81  	return len(op.Operation.Parameters) > 0
    82  }
    83  
    84  func (op *SwaggerOperation) WriteReqType(w io.Writer, importer *codegen.Importer) {
    85  	io.WriteString(w, `struct {
    86  `)
    87  
    88  	for _, parameter := range op.Parameters {
    89  		fieldName := codegen.ToUpperCamelCase(parameter.Name)
    90  		if parameter.Extensions[gen.XField] != nil {
    91  			fieldName = parameter.Extensions[gen.XField].(string)
    92  		}
    93  
    94  		field := common.NewField(fieldName)
    95  		field.AddTag("in", parameter.In)
    96  
    97  		tagName := parameter.Name
    98  		if parameter.Extensions[gen.XTagName] != nil {
    99  			tagName = fmt.Sprintf("%s", parameter.Extensions[gen.XTagName])
   100  		}
   101  		flags := make([]string, 0)
   102  		if !parameter.Required && !strings.Contains(tagName, "omitempty") {
   103  			flags = append(flags, "omitempty")
   104  		}
   105  		field.AddTag("name", tagName, flags...)
   106  		field.Comment = parameter.Description
   107  
   108  		if parameter.Extensions[gen.XTagValidate] != nil {
   109  			field.AddTag("validate", fmt.Sprintf("%s", parameter.Extensions[gen.XTagValidate]))
   110  		}
   111  
   112  		if parameter.Default != nil {
   113  			defaultValue := fmt.Sprintf("%v", parameter.Default)
   114  			if defaultValue != "" {
   115  				field.AddTag("default", defaultValue)
   116  			}
   117  		}
   118  
   119  		if parameter.Schema != nil {
   120  			field.Type = NewTypeGenerator(op.serviceName, importer).Type(parameter.Schema)
   121  		} else {
   122  			schema := spec.Schema{}
   123  			schema.Typed(parameter.Type, parameter.Format)
   124  			if parameter.Items != nil {
   125  				itemSchema := spec.Schema{}
   126  				itemSchema.Typed(parameter.Items.Type, parameter.Items.Format)
   127  				itemSchema.VendorExtensible = parameter.Items.VendorExtensible
   128  				schema.Items = &spec.SchemaOrArray{
   129  					Schema: &itemSchema,
   130  				}
   131  			}
   132  			schema.Extensions = parameter.Extensions
   133  			field.Type = NewTypeGenerator(op.serviceName, importer).Type(&schema)
   134  		}
   135  
   136  		io.WriteString(w, field.String())
   137  	}
   138  
   139  	io.WriteString(w, `
   140  }
   141  `)
   142  }
   143  
   144  func (op *SwaggerOperation) WriteRespBodyType(w io.Writer, importer *codegen.Importer) {
   145  	respBodySchema := op.respBodySchema()
   146  	if respBodySchema == nil {
   147  		io.WriteString(w, `[]byte`)
   148  		return
   149  	}
   150  	io.WriteString(w, NewTypeGenerator(op.serviceName, importer).Type(respBodySchema))
   151  }
   152  
   153  func (op *SwaggerOperation) respBodySchema() *spec.Schema {
   154  	if op.Responses == nil || op.Responses.StatusCodeResponses == nil {
   155  		return nil
   156  	}
   157  
   158  	var hasStringProduce = false
   159  
   160  	for _, produce := range op.Produces {
   161  		hasStringProduce = produce == httpx.MIMEHTML
   162  	}
   163  
   164  	var schema *spec.Schema
   165  
   166  	for code, r := range op.Responses.StatusCodeResponses {
   167  		if code >= 200 && code < 300 {
   168  			schema = &spec.Schema{}
   169  
   170  			if hasStringProduce {
   171  				schema.Typed("string", "")
   172  			} else {
   173  				schema.Typed("null", "")
   174  			}
   175  
   176  			if r.Ref.String() != "" && op.responses != nil {
   177  				if op.responses[common.RefName(r.Ref.String())].Schema != nil {
   178  					schema = op.responses[common.RefName(r.Ref.String())].Schema
   179  				}
   180  			}
   181  
   182  			if r.Schema != nil {
   183  				schema = r.Schema
   184  			}
   185  		}
   186  	}
   187  
   188  	return schema
   189  }