github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/cmd/internal/svc/codegen/httphandler.go (about)

     1  package codegen
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/unionj-cloud/go-doudou/toolkit/sliceutils"
     6  	"github.com/unionj-cloud/go-doudou/toolkit/stringutils"
     7  	"github.com/unionj-cloud/go-doudou/version"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"text/template"
    12  
    13  	"github.com/iancoleman/strcase"
    14  	"github.com/sirupsen/logrus"
    15  	"github.com/unionj-cloud/go-doudou/cmd/internal/astutils"
    16  )
    17  
    18  var httpHandlerTmpl = `/**
    19  * Generated by go-doudou {{.Version}}.
    20  * Don't edit!
    21  */
    22  package httpsrv
    23  
    24  import (
    25  	ddmodel "github.com/unionj-cloud/go-doudou/framework/http/model"
    26  	"net/http"
    27  	"os"
    28  )
    29  
    30  type {{.Meta.Name}}Handler interface {
    31  {{- range $m := .Meta.Methods }}
    32  	{{$m.Name}}(w http.ResponseWriter, r *http.Request)
    33  {{- end }}
    34  }
    35  
    36  func Routes(handler {{.Meta.Name}}Handler) []ddmodel.Route {
    37  	return []ddmodel.Route{
    38  		{{- range $m := .Meta.Methods }}
    39  		{
    40  			Name: "{{$m.Name}}",
    41  			Method: "{{$m.Name | httpMethod}}",
    42  			Pattern: {{- if eq $.RoutePatternStrategy 1}}"/{{$.Meta.Name | lower}}/{{$m.Name | noSplitPattern}}",{{- else }}"/{{$m.Name | pattern}}",{{- end }}
    43  			HandlerFunc: handler.{{$m.Name}},
    44  		},
    45  		{{- end }}
    46  	}
    47  }
    48  
    49  
    50  var RouteAnnotationStore = ddmodel.AnnotationStore{
    51  	{{- range $m := .Meta.Methods }}
    52  	{{- if $m.Annotations }}
    53  	"{{$m.Name}}": {
    54  		{{- range $a := $m.Annotations }}
    55  		{
    56  			Name:   "{{ $a.Name }}",
    57  			{{- if $a.Params }}
    58  			Params: []string{
    59  				{{- range $p := $a.Params }}
    60  				"{{ $p }}",
    61  				{{- end }}
    62  			},
    63  			{{- end }}
    64  		},
    65  		{{- end }}
    66  	},
    67  	{{- end }}
    68  	{{- end }}
    69  }
    70  `
    71  
    72  func pattern(method string) string {
    73  	httpMethods := []string{"GET", "POST", "PUT", "DELETE"}
    74  	snake := strcase.ToSnake(strings.ReplaceAll(method, "_", "."))
    75  	splits := strings.Split(snake, "_")
    76  	head := strings.ToUpper(splits[0])
    77  	if sliceutils.StringContains(httpMethods, head) {
    78  		splits = splits[1:]
    79  	}
    80  	clean := sliceutils.StringFilter(splits, func(item string) bool {
    81  		return stringutils.IsNotEmpty(item)
    82  	})
    83  	return strings.Join(clean, "/")
    84  }
    85  
    86  func noSplitPattern(method string) string {
    87  	httpMethods := []string{"GET", "POST", "PUT", "DELETE"}
    88  	snake := strcase.ToSnake(method)
    89  	splits := strings.Split(snake, "_")
    90  	head := strings.ToUpper(splits[0])
    91  	for _, m := range httpMethods {
    92  		if head == m {
    93  			return strings.ToLower(method[len(m):])
    94  		}
    95  	}
    96  	return strings.ToLower(method)
    97  }
    98  
    99  func httpMethod(method string) string {
   100  	httpMethods := []string{"GET", "POST", "PUT", "DELETE"}
   101  	snake := strcase.ToSnake(method)
   102  	splits := strings.Split(snake, "_")
   103  	head := strings.ToUpper(splits[0])
   104  	for _, m := range httpMethods {
   105  		if head == m {
   106  			return m
   107  		}
   108  	}
   109  	return "POST"
   110  }
   111  
   112  // GenHttpHandler generates http handler interface and routes
   113  func GenHttpHandler(dir string, ic astutils.InterfaceCollector, routePatternStrategy int) {
   114  	var (
   115  		err         error
   116  		handlerfile string
   117  		f           *os.File
   118  		tpl         *template.Template
   119  		httpDir     string
   120  		source      string
   121  		sqlBuf      bytes.Buffer
   122  		fi          os.FileInfo
   123  	)
   124  	httpDir = filepath.Join(dir, "transport/httpsrv")
   125  	if err = os.MkdirAll(httpDir, os.ModePerm); err != nil {
   126  		panic(err)
   127  	}
   128  
   129  	handlerfile = filepath.Join(httpDir, "handler.go")
   130  	fi, err = os.Stat(handlerfile)
   131  	if err != nil && !os.IsNotExist(err) {
   132  		panic(err)
   133  	}
   134  	if fi != nil {
   135  		logrus.Warningln("file handler.go will be overwritten")
   136  	}
   137  	if f, err = os.Create(handlerfile); err != nil {
   138  		panic(err)
   139  	}
   140  	defer f.Close()
   141  
   142  	funcMap := make(map[string]interface{})
   143  	funcMap["httpMethod"] = httpMethod
   144  	funcMap["pattern"] = pattern
   145  	funcMap["noSplitPattern"] = noSplitPattern
   146  	funcMap["lower"] = strings.ToLower
   147  	if tpl, err = template.New("handler.go.tmpl").Funcs(funcMap).Parse(httpHandlerTmpl); err != nil {
   148  		panic(err)
   149  	}
   150  	if err = tpl.Execute(&sqlBuf, struct {
   151  		RoutePatternStrategy int
   152  		Meta                 astutils.InterfaceMeta
   153  		Version              string
   154  	}{
   155  		RoutePatternStrategy: routePatternStrategy,
   156  		Meta:                 ic.Interfaces[0],
   157  		Version:              version.Release,
   158  	}); err != nil {
   159  		panic(err)
   160  	}
   161  	source = strings.TrimSpace(sqlBuf.String())
   162  	astutils.FixImport([]byte(source), handlerfile)
   163  }