Skip to content

Commit

Permalink
add fiber web framework support
Browse files Browse the repository at this point in the history
  • Loading branch information
alimy committed Apr 2, 2020
1 parent 56f4f55 commit 1862574
Show file tree
Hide file tree
Showing 27 changed files with 381 additions and 46 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![GoDoc](https://godoc.org/github.com/alimy/mir?status.svg)](https://pkg.go.dev/github.com/alimy/mir/v2)
[![sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?logo=sourcegraph)](https://sourcegraph.com/github.com/alimy/mir)

Mir is used for register handler to http router(eg: [Gin](https://github.com/gin-gonic/gin), [Chi](https://github.com/go-chi/chi), [Echo](https://github.com/labstack/echo), [Iris](https://github.com/kataras/iris), [Macaron](https://github.com/go-macaron/macaron), [Mux](https://github.com/gorilla/mux), [httprouter](https://github.com/julienschmidt/httprouter))
Mir is used for register handler to http router(eg: [Gin](https://github.com/gin-gonic/gin), [Chi](https://github.com/go-chi/chi), [Echo](https://github.com/labstack/echo), [Iris](https://github.com/kataras/iris), [Fiber](https://github.com/gofiber/fiber), [Macaron](https://github.com/go-macaron/macaron), [Mux](https://github.com/gorilla/mux), [httprouter](https://github.com/julienschmidt/httprouter))
depends on struct tag string info that defined in logic object's struct type field.

### Usage
Expand All @@ -13,7 +13,7 @@ Mir is used for register handler to http router(eg: [Gin](https://github.com/gin

```
% go get github.com/alimy/mir/mirc/v2@latest
% mirc new -d mir-examples
% mirc new -d mir-examples -t gin
% tree mir-examples
mir-examples
├── Makefile
Expand Down
11 changes: 11 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
GeneratorMux = "mux"
GeneratorEcho = "echo"
GeneratorIris = "iris"
GeneratorFiber = "fiber"
GeneratorMacaron = "macaron"
GeneratorHttpRouter = "httprouter"

Expand Down Expand Up @@ -50,12 +51,14 @@ type InitOpts struct {
ParserName string
SinkPath string
DefaultTag string
NoneQuery bool
Cleanup bool
}

// ParserOpts used for initial parser
type ParserOpts struct {
DefaultTag string
NoneQuery bool
}

// GeneratorOpts used for initial generator
Expand Down Expand Up @@ -85,6 +88,7 @@ func (opts Options) InitOpts() *InitOpts {
func (opts *InitOpts) ParserOpts() *ParserOpts {
return &ParserOpts{
DefaultTag: opts.DefaultTag,
NoneQuery: opts.NoneQuery,
}
}

Expand Down Expand Up @@ -183,6 +187,13 @@ func Cleanup(enable bool) Option {
})
}

// NoneQuery set parser whether parse query
func NoneQuery(enable bool) Option {
return optFunc(func(opts *InitOpts) {
opts.NoneQuery = enable
})
}

// DefaultTag set parser's default struct field tag string key
func DefaultTag(tag string) Option {
return optFunc(func(opts *InitOpts) {
Expand Down
1 change: 1 addition & 0 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func init() {
&mirGenerator{name: core.GeneratorMux},
&mirGenerator{name: core.GeneratorEcho},
&mirGenerator{name: core.GeneratorIris},
&mirGenerator{name: core.GeneratorFiber},
&mirGenerator{name: core.GeneratorMacaron},
&mirGenerator{name: core.GeneratorHttpRouter},
)
Expand Down
1 change: 1 addition & 0 deletions internal/generator/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var tmplFiles = map[string]string{
core.GeneratorMux: "mux_iface.tmpl",
core.GeneratorEcho: "echo_iface.tmpl",
core.GeneratorIris: "iris_iface.tmpl",
core.GeneratorFiber: "fiber_iface.tmpl",
core.GeneratorMacaron: "macaron_iface.tmpl",
core.GeneratorHttpRouter: "httprouter_iface.tmpl",
}
Expand Down
28 changes: 28 additions & 0 deletions internal/generator/templates/fiber_iface.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Code generated by go-mir. DO NOT EDIT.

package {{ .PkgName }}

import (
"github.com/gofiber/fiber"
)

{{if notEmptyStr .Comment }}// {{.Comment}}{{end}}
type {{.TypeName}} interface {
{{if notEmptyStr .Chain }}// Chain provide handlers chain for fiber
{{.Chain}}() []func(*Ctx)
{{end}}
{{range .Fields}}{{if notEmptyStr .Comment }} // {{.Comment}}
{{.MethodName}}(c *fiber.Ctx){{else}} {{.MethodName}}(c *fiber.Ctx){{end}}
{{end}}
}

// Register{{.TypeName}}Servant register {{.TypeName}} servant to fiber
func Register{{.TypeName}}Servant(app *fiber.App, s {{.TypeName}}) {
{{if notEmptyStr .Group }} router := app.Group("{{.Group}}"){{else}} router := app{{end}}
{{if notEmptyStr .Chain }} // use chain for router
middlewares := s.{{.Chain}}()
router.Use(middlewares...)
{{end}}
// register routes info to router
{{range .Fields}}{{if eq .HttpMethod "GET" }} router.Get("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "POST"}} router.Post("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "PUT"}} router.Put("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "DELETE"}} router.Delete("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "HEAD"}} router.Head("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "OPTIONS"}} router.Options("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "TRACE"}} router.Trace("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "PATCH"}} router.Patch("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "CONNECT"}} router.Connect("{{.Path}}", s.{{.MethodName}}){{else if eq .HttpMethod "ANY" }} router.All("{{.Path}}", s.{{.MethodName}}){{end}}
{{end}}}
23 changes: 23 additions & 0 deletions internal/generator/templates_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions internal/parser/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ func (r *reflex) tagInfoFrom(field reflect.StructField) (*tagInfo, error) {
if len(tag) == 0 && !info.isGroup {
return nil, errNoPathInfo
}
i = 0
for i < len(tag) && tag[i] != '?' && tag[i] != '#' {
i++
for i = 0; i < len(tag) && tag[i] != '#'; i++ {
if !r.noneQuery && tag[i] == '?' {
break
}
}
info.Path = tag[0:i]
tag = tag[i:]
Expand Down
14 changes: 7 additions & 7 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/alimy/mir/v2/core"
"github.com/alimy/mir/v2/internal/container"
"github.com/alimy/mir/v2/internal/naming"
)

func init() {
Expand All @@ -19,7 +18,8 @@ func init() {

// mirParser parse for struct tag
type mirParser struct {
tagName string
tagName string
noneQuery bool
}

// Name name of parser
Expand All @@ -32,7 +32,7 @@ func (p *mirParser) Init(opts *core.ParserOpts) error {
if opts == nil {
return errors.New("init opts is nil")
}
p.tagName = opts.DefaultTag
p.tagName, p.noneQuery = opts.DefaultTag, opts.NoneQuery
if p.tagName == "" {
p.tagName = defaultTag
}
Expand All @@ -44,7 +44,7 @@ func (p *mirParser) Parse(entries []interface{}) (core.Descriptors, error) {
if len(entries) == 0 {
return nil, errors.New("entries is empty")
}
r := &reflex{tagName: p.tagName, ns: naming.NewSnakeNamingStrategy()}
r := newReflex(p.tagName, p.noneQuery)
return r.parse(entries)
}

Expand All @@ -56,10 +56,10 @@ func (p *mirParser) ParseContext(ctx core.MirCtx, entries []interface{}) {
wg := &sync.WaitGroup{}
for _, entry := range entries {
wg.Add(1)
go func(ctx core.MirCtx, wg *sync.WaitGroup, ifaceSink chan<- *core.IfaceDescriptor, tagName string, entry interface{}) {
go func(ctx core.MirCtx, wg *sync.WaitGroup, ifaceSink chan<- *core.IfaceDescriptor, entry interface{}) {
defer wg.Done()

r := &reflex{tagName: tagName}
r := newReflex(p.tagName, p.noneQuery)
iface, err := r.ifaceFrom(entry)
if err != nil {
ctx.Cancel(err)
Expand All @@ -72,7 +72,7 @@ func (p *mirParser) ParseContext(ctx core.MirCtx, entries []interface{}) {
}
ifaceSink <- iface
core.Logus("delivered iface: %s.%s", iface.PkgName, iface.TypeName)
}(ctx, wg, ifaceSink, p.tagName, entry)
}(ctx, wg, ifaceSink, entry)
}
wg.Wait()

Expand Down
13 changes: 11 additions & 2 deletions internal/parser/reflex.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (

// reflex real parser
type reflex struct {
ns naming.NamingStrategy
tagName string
ns naming.NamingStrategy
tagName string
noneQuery bool
}

// reflex get Descriptors from parse entries
Expand Down Expand Up @@ -134,3 +135,11 @@ func (r *reflex) fieldFrom(t *tagInfo) *core.FieldDescriptor {
MethodName: t.fieldName,
}
}

func newReflex(tagName string, noneQuery bool) *reflex {
return &reflex{
ns: naming.NewSnakeNamingStrategy(),
tagName: tagName,
noneQuery: noneQuery,
}
}
1 change: 1 addition & 0 deletions mirc/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/macaron
/echo
/iris
/fiber
2 changes: 1 addition & 1 deletion mirc/cmd/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func init() {
// parse flags for agentCmd
newCmd.Flags().StringVarP(&dstPath, "dst", "d", ".", "genereted destination target directory")
newCmd.Flags().StringVarP(&pkgName, "pkg", "p", "github.com/alimy/mir-example", "project's package name")
newCmd.Flags().StringVarP(&style, "type", "t", "gin", "generated engine type style eg: gin,chi,mux,echo,iris,macaron,httprouter")
newCmd.Flags().StringVarP(&style, "type", "t", "gin", "generated engine type style eg: gin,chi,mux,echo,iris,fiber,macaron,httprouter")

// register agentCmd as sub-command
register(newCmd)
Expand Down
10 changes: 10 additions & 0 deletions mirc/cmd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ var tmplFiles = map[string]map[string]tmplInfo{
"mirc/routes/v1/site.go": {"iris_mirc_routes_site_v1.tmpl", false},
"mirc/routes/v2/site.go": {"iris_mirc_routes_site_v2.tmpl", false},
},
"fiber": {
"Makefile": {"makefile.tmpl", false},
"README.md": {"readme.tmpl", false},
"go.mod": {"fiber_go_mod.tmpl", true},
"main.go": {"fiber_main.tmpl", false},
"mirc/main.go": {"fiber_mirc_main.tmpl", true},
"mirc/routes/site.go": {"fiber_mirc_routes_site.tmpl", false},
"mirc/routes/v1/site.go": {"fiber_mirc_routes_site_v1.tmpl", false},
"mirc/routes/v2/site.go": {"fiber_mirc_routes_site_v2.tmpl", false},
},
"macaron": {
"Makefile": {"makefile.tmpl", false},
"README.md": {"readme.tmpl", false},
Expand Down
2 changes: 1 addition & 1 deletion mirc/cmd/templates/chi_go_mod.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module {{ .PkgName }}
go 1.12

require (
github.com/alimy/mir/v2 v2.3.2
github.com/alimy/mir/v2 v2.4.0
github.com/go-chi/chi v4.0.3+incompatible
)
2 changes: 1 addition & 1 deletion mirc/cmd/templates/echo_go_mod.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module {{ .PkgName }}
go 1.12

require (
github.com/alimy/mir/v2 v2.3.2
github.com/alimy/mir/v2 v2.4.0
github.com/labstack/echo/v4 v4.1.15
)
8 changes: 8 additions & 0 deletions mirc/cmd/templates/fiber_go_mod.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module {{ .PkgName }}

go 1.12

require (
github.com/alimy/mir/v2 v2.4.0
github.com/gofiber/fiber v1.8.431
)
23 changes: 23 additions & 0 deletions mirc/cmd/templates/fiber_main.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"log"

"github.com/gofiber/fiber"
)

func main() {
app := fiber.New()

// register servants to fiber
registerServants(app)

// start servant service
if err := app.Listen(3000); err != nil {
log.Fatal(err)
}
}

func registerServants(app *fiber.App) {
// TODO: register routes to app
}
27 changes: 27 additions & 0 deletions mirc/cmd/templates/fiber_mirc_main.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"log"

"github.com/alimy/mir/v2/core"
"github.com/alimy/mir/v2/engine"

_ "{{ .PkgName }}/mirc/routes"
_ "{{ .PkgName }}/mirc/routes/v1"
_ "{{ .PkgName }}/mirc/routes/v2"
)

//go:generate go run main.go
func main() {
log.Println("generate code start")
opts := core.Options{
core.RunMode(core.InSerialMode),
core.GeneratorName(core.GeneratorFiber),
core.NoneQuery(true),
core.SinkPath("./gen"),
}
if err := engine.Generate(opts); err != nil {
log.Fatal(err)
}
log.Println("generate code finish")
}
17 changes: 17 additions & 0 deletions mirc/cmd/templates/fiber_mirc_routes_site.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package routes

import (
"github.com/alimy/mir/v2"
"github.com/alimy/mir/v2/engine"
)

func init() {
engine.AddEntry(new(Site))
}

// Site site interface info
type Site struct {
Chain mir.Chain `mir:"-"`
Index mir.Get `mir:"/index/"`
Articles mir.Get `mir:"/articles/:category/"`
}
18 changes: 18 additions & 0 deletions mirc/cmd/templates/fiber_mirc_routes_site_v1.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package v1

import (
"github.com/alimy/mir/v2"
"github.com/alimy/mir/v2/engine"
)

func init() {
engine.AddEntry(new(Site))
}

// Site site v1 interface info
type Site struct {
Chain mir.Chain `mir:"-"`
Group mir.Group `mir:"v1"`
Index mir.Get `mir:"/index/"`
Articles mir.Get `mir:"/articles/:category/"`
}
Loading

0 comments on commit 1862574

Please sign in to comment.