Skip to content

Commit f543995

Browse files
committed
modify grpc+http generation code
1 parent f35ea09 commit f543995

File tree

14 files changed

+313
-39
lines changed

14 files changed

+313
-39
lines changed

cmd/protoc-gen-go-gin/Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ service:
2525
--plugin=./protoc-gen-go-gin* \
2626
api/v1/*.proto
2727

28+
29+
mix:
30+
@go build
31+
protoc --proto_path=. --proto_path=./third_party \
32+
--go_out=. --go_opt=paths=source_relative \
33+
--go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=mix \
34+
--go-gin_opt=moduleName=yourModuleName --go-gin_opt=serverName=yourServerName \
35+
--plugin=./protoc-gen-go-gin* \
36+
api/v1/*.proto
37+
2838
router-mr:
2939
@go build
3040
protoc --proto_path=. --proto_path=./third_party \
@@ -53,6 +63,15 @@ service-mr:
5363
--plugin=./protoc-gen-go-gin* \
5464
api/v1/*.proto
5565

66+
mix-mr:
67+
@go build
68+
protoc --proto_path=. --proto_path=./third_party \
69+
--go_out=. --go_opt=paths=source_relative \
70+
--go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=mix \
71+
--go-gin_opt=moduleName=yourModuleName --go-gin_opt=serverName=yourServerName --go-gin_opt=suitedMonoRepo=true \
72+
--plugin=./protoc-gen-go-gin* \
73+
api/v1/*.proto
74+
5675
fmt:
5776
gofmt -s -w .
5877

cmd/protoc-gen-go-gin/internal/generate/handler/gen.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@ import (
1010
)
1111

1212
// GenerateFiles generate handler logic, router, error code files.
13-
func GenerateFiles(file *protogen.File) ([]byte, []byte, []byte) {
13+
func GenerateFiles(file *protogen.File, isMixType bool) ([]byte, []byte, []byte) {
1414
if len(file.Services) == 0 {
1515
return nil, nil, nil
1616
}
1717

1818
pss := parse.GetServices(file)
19-
logicContent := genHandlerLogicFile(pss)
20-
routerFileContent := genRouterFile(pss)
21-
errCodeFileContent := genErrCodeFile(pss)
19+
20+
var logicContent, routerFileContent, errCodeFileContent []byte
21+
22+
if !isMixType {
23+
logicContent = genHandlerLogicFile(pss)
24+
routerFileContent = genRouterFile(pss)
25+
errCodeFileContent = genErrCodeFile(pss)
26+
} else {
27+
logicContent = genMixLogicFile(pss)
28+
routerFileContent = genMixRouterFile(pss)
29+
}
2230

2331
return logicContent, routerFileContent, errCodeFileContent
2432
}
@@ -38,6 +46,16 @@ func genErrCodeFile(fields []*parse.PbService) []byte {
3846
return cf.execute()
3947
}
4048

49+
func genMixLogicFile(fields []*parse.PbService) []byte {
50+
mlf := &mixLogicFields{PbServices: fields}
51+
return mlf.execute()
52+
}
53+
54+
func genMixRouterFile(fields []*parse.PbService) []byte {
55+
mrf := &mixRouterFields{PbServices: fields}
56+
return mrf.execute()
57+
}
58+
4159
type handlerLogicFields struct {
4260
PbServices []*parse.PbService
4361
}
@@ -75,6 +93,30 @@ func (f *errCodeFields) execute() []byte {
7593
return handleSplitLineMark(data)
7694
}
7795

96+
type mixLogicFields struct {
97+
PbServices []*parse.PbService
98+
}
99+
100+
func (f *mixLogicFields) execute() []byte {
101+
buf := new(bytes.Buffer)
102+
if err := mixLogicTmpl.Execute(buf, f); err != nil {
103+
panic(err)
104+
}
105+
return handleSplitLineMark(buf.Bytes())
106+
}
107+
108+
type mixRouterFields struct {
109+
PbServices []*parse.PbService
110+
}
111+
112+
func (f *mixRouterFields) execute() []byte {
113+
buf := new(bytes.Buffer)
114+
if err := mixRouterTmpl.Execute(buf, f); err != nil {
115+
panic(err)
116+
}
117+
return handleSplitLineMark(buf.Bytes())
118+
}
119+
78120
var splitLineMark = []byte(`// ---------- Do not delete or move this split line, this is the merge code marker ----------`)
79121

80122
func handleSplitLineMark(data []byte) []byte {

cmd/protoc-gen-go-gin/internal/generate/handler/template.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ func init() {
2121
panic(err)
2222
}
2323

24+
mixLogicTmpl, err = template.New("mixLogic").Parse(mixLogicTmplRaw)
25+
if err != nil {
26+
panic(err)
27+
}
28+
mixRouterTmpl, err = template.New("mixRouter").Parse(mixRouterTmplRaw)
29+
if err != nil {
30+
panic(err)
31+
}
32+
2433
rand.Seed(time.Now().UnixNano())
2534
}
2635

@@ -138,8 +147,131 @@ func {{.LowerName}}Router(
138147
groupPathMiddlewares,
139148
singlePathMiddlewares,
140149
iService,
150+
serverNameExampleV1.With{{.Name}}Logger(logger.Get()),
141151
serverNameExampleV1.With{{.Name}}HTTPResponse(),
152+
serverNameExampleV1.With{{.Name}}ErrorToHTTPCode(
153+
// Set some error codes to standard http return codes,
154+
// by default there is already ecode.InternalServerError and ecode.ServiceUnavailable
155+
// example:
156+
// ecode.Forbidden, ecode.LimitExceed,
157+
),
158+
)
159+
}
160+
161+
// you can set the middleware of a route group, or set the middleware of a single route,
162+
// or you can mix them, pay attention to the duplication of middleware when mixing them,
163+
// it is recommended to set the middleware of a single route in preference
164+
func {{.LowerName}}Middlewares(c *middlewareConfig) {
165+
// set up group route middleware, group path is left prefix rules,
166+
// if the left prefix is hit, the middleware will take effect, e.g. group route is /api/v1, route /api/v1/{{.LowerName}}/:id will take effect
167+
// c.setGroupPath("/api/v1/{{.LowerName}}", middleware.Auth())
168+
169+
// set up single route middleware, just uncomment the code and fill in the middlewares, nothing else needs to be changed
170+
{{- range .Methods}}
171+
{{if eq .InvokeType 0}}{{if .Path}}//c.setSinglePath("{{.Method}}", "{{.Path}}", middleware.Auth()){{end}}{{end}}
172+
{{- end}}
173+
}
174+
175+
// ---------- Do not delete or move this split line, this is the merge code marker ----------
176+
177+
{{- end}}
178+
`
179+
180+
mixLogicTmpl *template.Template
181+
mixLogicTmplRaw = `// Code generated by https://github.com/zhufuyi/sponge
182+
183+
package handler
184+
185+
import (
186+
"context"
187+
188+
serverNameExampleV1 "moduleNameExample/api/serverNameExample/v1"
189+
"moduleNameExample/internal/service"
190+
)
191+
192+
{{- range .PbServices}}
193+
194+
var _ serverNameExampleV1.{{.Name}}Logicer = (*{{.LowerName}}Handler)(nil)
195+
196+
type {{.LowerName}}Handler struct {
197+
server serverNameExampleV1.{{.Name}}Server
198+
}
199+
200+
// New{{.Name}}Handler create a handler
201+
func New{{.Name}}Handler() serverNameExampleV1.{{.Name}}Logicer {
202+
return &{{.LowerName}}Handler{
203+
server: service.New{{.Name}}Server(),
204+
}
205+
}
206+
207+
{{- range .Methods}}
208+
209+
{{if eq .InvokeType 0}}{{if .Path}}{{.Comment}}
210+
func (h *{{.LowerServiceName}}Handler) {{.MethodName}}(ctx context.Context, req *serverNameExampleV1.{{.Request}}) (*serverNameExampleV1.{{.Reply}}, error) {
211+
return h.server.{{.MethodName}}(ctx, req)
212+
}{{end}}{{end}}
213+
214+
{{- end}}
215+
216+
// ---------- Do not delete or move this split line, this is the merge code marker ----------
217+
218+
{{- end}}
219+
`
220+
221+
mixRouterTmpl *template.Template
222+
mixRouterTmplRaw = `// Code generated by https://github.com/zhufuyi/sponge
223+
224+
package routers
225+
226+
import (
227+
"context"
228+
229+
"github.com/gin-gonic/gin"
230+
"google.golang.org/grpc/metadata"
231+
232+
"github.com/zhufuyi/sponge/pkg/gin/middleware"
233+
"github.com/zhufuyi/sponge/pkg/logger"
234+
235+
serverNameExampleV1 "moduleNameExample/api/serverNameExample/v1"
236+
"moduleNameExample/internal/handler"
237+
)
238+
239+
func init() {
240+
allMiddlewareFns = append(allMiddlewareFns, func(c *middlewareConfig) {
241+
{{- range .PbServices}}
242+
{{.LowerName}}Middlewares(c)
243+
{{- end}}
244+
})
245+
246+
allRouteFns = append(allRouteFns,
247+
func(r *gin.Engine, groupPathMiddlewares map[string][]gin.HandlerFunc, singlePathMiddlewares map[string][]gin.HandlerFunc) {
248+
{{- range .PbServices}}
249+
{{.LowerName}}Router(r, groupPathMiddlewares, singlePathMiddlewares, handler.New{{.Name}}Handler())
250+
{{- end}}
251+
})
252+
}
253+
254+
{{- range .PbServices}}
255+
256+
func {{.LowerName}}Router(
257+
r *gin.Engine,
258+
groupPathMiddlewares map[string][]gin.HandlerFunc,
259+
singlePathMiddlewares map[string][]gin.HandlerFunc,
260+
iService serverNameExampleV1.{{.Name}}Logicer) {
261+
ctxFn := func(c *gin.Context) context.Context {
262+
md := metadata.New(map[string]string{
263+
middleware.ContextRequestIDKey: middleware.GCtxRequestID(c),
264+
})
265+
return metadata.NewIncomingContext(c.Request.Context(), md)
266+
}
267+
serverNameExampleV1.Register{{.Name}}Router(
268+
r,
269+
groupPathMiddlewares,
270+
singlePathMiddlewares,
271+
iService,
142272
serverNameExampleV1.With{{.Name}}Logger(logger.Get()),
273+
serverNameExampleV1.With{{.Name}}RPCResponse(),
274+
serverNameExampleV1.With{{.Name}}WrapCtx(ctxFn),
143275
serverNameExampleV1.With{{.Name}}ErrorToHTTPCode(
144276
// Set some error codes to standard http return codes,
145277
// by default there is already ecode.InternalServerError and ecode.ServiceUnavailable

cmd/protoc-gen-go-gin/internal/generate/service/template.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ func {{.LowerName}}Router(
147147
groupPathMiddlewares,
148148
singlePathMiddlewares,
149149
iService,
150-
serverNameExampleV1.With{{.Name}}RPCResponse(),
151150
serverNameExampleV1.With{{.Name}}Logger(logger.Get()),
151+
serverNameExampleV1.With{{.Name}}RPCResponse(),
152+
serverNameExampleV1.With{{.Name}}WrapCtx(ctxFn),
152153
serverNameExampleV1.With{{.Name}}RPCStatusToHTTPCode(
153154
// Set some error codes to standard http return codes,
154155
// by default there is already ecode.StatusInternalServerError and ecode.StatusServiceUnavailable
155156
// example:
156157
// ecode.StatusUnimplemented, ecode.StatusAborted,
157158
),
158-
serverNameExampleV1.With{{.Name}}WrapCtx(ctxFn),
159159
)
160160
}
161161

cmd/protoc-gen-go-gin/main.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
const (
2222
handlerPlugin = "handler"
2323
servicePlugin = "service"
24+
mixPlugin = "mix" // code generated for the http+grpc approach
2425

2526
helpInfo = `
2627
# generate *_router.pb.go file
@@ -34,6 +35,10 @@ protoc --proto_path=. --proto_path=./third_party --go-gin_out=. --go-gin_opt=pat
3435
protoc --proto_path=. --proto_path=./third_party --go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=service \
3536
--go-gin_opt=moduleName=yourModuleName --go-gin_opt=serverName=yourServerName *.proto
3637
38+
# generate *_router.pb.go, *.go(tmpl), *_router.go, *_rpc.go files
39+
protoc --proto_path=. --proto_path=./third_party --go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=mix \
40+
--go-gin_opt=moduleName=yourModuleName --go-gin_opt=serverName=yourServerName *.proto
41+
3742
# if you want the generated code to suited to mono-repo, you need to specify the parameter --go-gin_opt=suitedMonoRepo=true
3843
3944
Tip:
@@ -52,6 +57,7 @@ Usage example:
5257
`
5358
)
5459

60+
// nolint
5561
func main() {
5662
var h bool
5763
flag.BoolVar(&h, "h", false, "help information")
@@ -65,7 +71,7 @@ func main() {
6571

6672
var plugin, moduleName, serverName, logicOut, routerOut, ecodeOut string
6773
var suitedMonoRepo bool
68-
flags.StringVar(&plugin, "plugin", "", "plugin name, supported values: handler or service")
74+
flags.StringVar(&plugin, "plugin", "", "plugin name, supported values: handler, service and mix")
6975
flags.StringVar(&moduleName, "moduleName", "", "module name for plugin")
7076
flags.StringVar(&serverName, "serverName", "", "server name for plugin")
7177
flags.StringVar(&logicOut, "logicOut", "", "directory of logical template code generated by the plugin, "+
@@ -79,7 +85,7 @@ func main() {
7985
}
8086

8187
options.Run(func(gen *protogen.Plugin) error {
82-
handlerFlag, serviceFlag := false, false
88+
handlerFlag, serviceFlag, mixFlag := false, false, false
8389
pluginName := strings.ReplaceAll(plugin, " ", "")
8490
dirName := "internal"
8591
if suitedMonoRepo {
@@ -108,6 +114,15 @@ func main() {
108114
if ecodeOut == "" {
109115
ecodeOut = dirName + "/ecode"
110116
}
117+
case mixPlugin:
118+
mixFlag = true
119+
handlerFlag = true
120+
if logicOut == "" {
121+
logicOut = dirName + "/handler"
122+
}
123+
if routerOut == "" {
124+
routerOut = dirName + "/routers"
125+
}
111126
case "":
112127
default:
113128
return fmt.Errorf("protoc-gen-go-gin: unknown plugin %q, only 'service' and 'handler' are supported", plugin)
@@ -126,14 +141,14 @@ func main() {
126141
router.GenerateFile(gen, f)
127142

128143
if handlerFlag {
129-
err := saveHandlerAndRouterFiles(f, moduleName, serverName, logicOut, routerOut, ecodeOut, suitedMonoRepo)
144+
err := saveHandlerAndRouterFiles(f, moduleName, serverName, logicOut, routerOut, ecodeOut, suitedMonoRepo, mixFlag)
130145
if err != nil {
131-
continue // skip error, process the next protobuf file
146+
return err
132147
}
133148
} else if serviceFlag {
134149
err := saveServiceAndRouterFiles(f, moduleName, serverName, logicOut, routerOut, ecodeOut, suitedMonoRepo)
135150
if err != nil {
136-
continue // skip error, process the next protobuf file
151+
return err
137152
}
138153
}
139154
}
@@ -142,9 +157,9 @@ func main() {
142157
}
143158

144159
func saveHandlerAndRouterFiles(f *protogen.File, moduleName string, serverName string,
145-
logicOut string, routerOut string, ecodeOut string, suitedMonoRepo bool) error {
160+
logicOut string, routerOut string, ecodeOut string, suitedMonoRepo bool, isMixType bool) error {
146161
filenamePrefix := f.GeneratedFilenamePrefix
147-
handlerLogicContent, routerContent, errCodeFileContent := handler.GenerateFiles(f)
162+
handlerLogicContent, routerContent, errCodeFileContent := handler.GenerateFiles(f, isMixType)
148163

149164
filePath := filenamePrefix + ".go"
150165
err := saveFile(moduleName, serverName, logicOut, filePath, handlerLogicContent, false, handlerPlugin, suitedMonoRepo)
@@ -158,10 +173,12 @@ func saveHandlerAndRouterFiles(f *protogen.File, moduleName string, serverName s
158173
return err
159174
}
160175

161-
filePath = filenamePrefix + "_http.go"
162-
err = saveFileSimple(ecodeOut, filePath, errCodeFileContent, false)
163-
if err != nil {
164-
return err
176+
if !isMixType {
177+
filePath = filenamePrefix + "_http.go"
178+
err = saveFileSimple(ecodeOut, filePath, errCodeFileContent, false)
179+
if err != nil {
180+
return err
181+
}
165182
}
166183

167184
return nil

cmd/sponge/commands/generate/handler-pb.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ func (g *handlerPbGenerator) generateCode() (string, error) {
182182
default:
183183
return "", errors.New("unsupported db driver: " + g.dbDriver)
184184
}
185+
ignoreFiles = append(ignoreFiles, "handler/userExample.go.service")
185186

186187
r.SetSubDirsAndFiles(subDirs)
187188
r.SetIgnoreSubDirs(ignoreDirs...)
@@ -246,7 +247,7 @@ func (g *handlerPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
246247
},
247248
{
248249
Old: "userExampleNO = 1",
249-
New: fmt.Sprintf("userExampleNO = %d", rand.Intn(100)),
250+
New: fmt.Sprintf("userExampleNO = %d", rand.Intn(99)+1),
250251
},
251252
{
252253
Old: g.moduleName + "/pkg",

0 commit comments

Comments
 (0)