Skip to content

Commit

Permalink
add custom field chain support for Iris engine
Browse files Browse the repository at this point in the history
  • Loading branch information
alimy committed May 23, 2023
1 parent 6696a61 commit 343ddf4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/tutorials.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ type User struct {
* 函数参数的类型限定为 `mir.(Get/Put/Post/Delete/Head/Patch/Trace/Connect/Options/Any/Chain)`类型、Go `struct`类型;
* Go `struct`类型作为函数参数只能放置在最后一个参数位置,表示接口需要这个`struct`类型表示的参数类型的从http request中Binding后的结果对象作为请求参数;
* 函数参数中的非最后一个参数,可以有多个,类型限定为`mir.(Get/Put/Post/Delete/Head/Patch/Trace/Connect/Options/Any)`类型;表示的意思是这个接口将注册为相应的HTTP Method handler,比如`mir.Post`表示将这个接口注册为 HTTP Method 为`POST` 的handler `router.Handle("POST", "/login/", func(...){...})`; `mir.Any` 表示将这个接口注册为所有HTTP Method handler;
* 函数参数中如果有`Chain`表示这个接口有自定义的HTTP引擎中间件的方法,比如gin引擎的`gin.HandlersChain`,会与接口一起注册,目前仅支持`Gin`/`Chi`/`Echo`/`Hertz`引擎;
* 函数参数中如果有`Chain`表示这个接口有自定义的HTTP引擎中间件的方法,比如gin引擎的`gin.HandlersChain`,会与接口一起注册,目前仅支持`Gin`/`Chi`/`Echo`/`Hertz`/`Iris`引擎;
* 函数返回值至多只有一个,可以没有,也可以有一个,限定类型为Go `struct`类型;
* 函数中的最后一个参数和返回值,如果有的话,限定类型为Go `struct`类型,并且可以说与接口定义的同一个包中的结构体,也可以是其他包中的结构体;
Expand Down
37 changes: 29 additions & 8 deletions internal/generator/templates/iris_iface.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ type {{.TypeName}}Binding interface {
mustEmbedUnimplemented{{.TypeName}}Binding()
}
{{end}}
{{if .IsUseFieldChain }}
type {{.TypeName}}Chain interface {
{{range .ChainFields }} Chain{{.MethodName}}() context.Handlers
{{end}}

mustEmbedUnimplemented{{.TypeName}}Chain()
}
{{end}}

type {{.TypeName}}Render interface {
{{range .Fields}} {{if notEmptyStr .OutName }}Render{{.MethodName}}(context.Context, *{{ .OutName }}, mir.Error){{else}}Render{{.MethodName}}(context.Context, mir.Error){{end}}
Expand All @@ -42,14 +50,14 @@ type {{.TypeName}}Render interface {
}

// Register{{.TypeName}}Servant register {{.TypeName}} servant to iris
func Register{{.TypeName}}Servant(app *iris.Application, s {{.TypeName}}{{if .IsUseBinding }}, b {{.TypeName}}Binding{{end}}, r {{.TypeName}}Render ) {
func Register{{.TypeName}}Servant(app *iris.Application, s {{.TypeName}}{{if .IsUseBinding }}, b {{.TypeName}}Binding{{end}}, r {{.TypeName}}Render{{if .IsUseFieldChain }}, c {{.TypeName}}Chain{{end}}) {
{{if notEmptyStr .Group }} router := app.Party("{{.Group}}"){{else}} router := app{{end}}
{{if notEmptyStr .Chain }} // use chain for party
middlewares := s.{{.Chain}}()
router.Use(middlewares...)
{{end}}
// register routes info to router
{{range .Fields}}{{if .NotHttpAny }} router.Handle("{{.HttpMethod}}", "{{.Path}}", func(c context.Context) {{if $.WatchCtxDone }}{
{{range .Fields}}{{if .NotHttpAny }} router.Handle("{{.HttpMethod}}", "{{.Path}}", {{if .IsFieldChain }}append(c.Chain{{.MethodName}}(), {{end}}func(c context.Context) {{if $.WatchCtxDone }}{
select {
case <- c.Request().Context().Done():
return
Expand All @@ -64,8 +72,8 @@ func Register{{.TypeName}}Servant(app *iris.Application, s {{.TypeName}}{{if .Is
{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}(req)
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}(req)){{end}}{{else}}{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}()
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}()){{end}}{{end}}
})
{{else if .JustHttpAny}} router.Any("{{.Path}}", func(c context.Context) {{if $.WatchCtxDone }}{
}{{if .IsFieldChain }})...{{end}})
{{else if .JustHttpAny}} router.Any("{{.Path}}", {{if .IsFieldChain }}append(c.Chain{{.MethodName}}(), {{end}}func(c context.Context) {{if $.WatchCtxDone }}{
select {
case <- c.Request().Context().Done():
return
Expand All @@ -80,9 +88,9 @@ func Register{{.TypeName}}Servant(app *iris.Application, s {{.TypeName}}{{if .Is
{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}(req)
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}(req)){{end}}{{else}}{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}()
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}()){{end}}{{end}}
})
}{{if .IsFieldChain }})...{{end}})
{{else}}{{$field := .}} {
h := func(c context.Context) {{if $.WatchCtxDone }}{
h := {{if .IsFieldChain }}append(c.Chain{{.MethodName}}(), {{end}}func(c context.Context) {{if $.WatchCtxDone }}{
select {
case <- c.Request().Context().Done():
return
Expand All @@ -97,8 +105,8 @@ func Register{{.TypeName}}Servant(app *iris.Application, s {{.TypeName}}{{if .Is
{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}(req)
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}(req)){{end}}{{else}}{{if notEmptyStr .OutName}}resp, err := s.{{.MethodName}}()
r.Render{{.MethodName}}(c, resp, err){{else}}r.Render{{.MethodName}}(c, s.{{.MethodName}}()){{end}}{{end}}
}
{{range .AnyHttpMethods}} router.Handle("{{.}}", "{{$field.Path}}", h)
}{{if .IsFieldChain }}){{end}}
{{range .AnyHttpMethods}} router.Handle("{{.}}", "{{$field.Path}}", h{{if $field.IsFieldChain }}...{{end}})
{{end}} }
{{end}}
{{end}}}
Expand Down Expand Up @@ -151,3 +159,16 @@ type {{$unimplementedBinding}} struct {
{{end}}
func (b *{{$unimplementedBinding}})mustEmbedUnimplemented{{.TypeName}}Binding() {}
{{end}}
{{if .IsUseFieldChain }}
{{ $unimplementedChain := print "Unimplemented" .TypeName "Chain" }}
// {{$unimplementedChain}} can be embedded to have forward compatible implementations.
type {{$unimplementedChain}} struct {
}

{{range .Fields}}{{if .IsFieldChain }}func (b *{{$unimplementedChain}}) Chain{{.MethodName}}() context.Handlers {
return nil
}
{{end}}
{{end}}
func (b *{{$unimplementedChain}})mustEmbedUnimplemented{{.TypeName}}Chain() {}
{{end}}

0 comments on commit 343ddf4

Please sign in to comment.