Skip to content

Commit

Permalink
更新部分功能
Browse files Browse the repository at this point in the history
  • Loading branch information
刘洪宝 committed Nov 23, 2018
1 parent 9e426f7 commit c9ccb02
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 45 deletions.
34 changes: 34 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bingo_router

import (
"net/http"
"github.com/json-iterator/go"
)

// 上下文结构体
type Context struct {
Writer http.ResponseWriter // 响应
Request *http.Request // 请求
Params Params //参数
//Session Session // 保存session
}

// 重定向,传入路径和状态码
func (c *Context) Redirect(path string) {
url := c.Request.URL.Host + path
http.Redirect(c.Writer, c.Request, url, http.StatusFound)
}

// 输出字符串
func (c *Context) String(data string) {
c.Writer.WriteHeader(http.StatusOK)
c.Writer.Write([]byte(data))
}

// 输出json
func (c *Context) ResponseJson(data interface{}) {
json := jsoniter.ConfigCompatibleWithStandardLibrary
d, _ := json.Marshal(data)
c.Writer.WriteHeader(http.StatusOK)
c.Writer.Write([]byte(d))
}
43 changes: 43 additions & 0 deletions controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package bingo_router

// 控制器接口
type IController interface {
Index(c *Context) // 对应 get : path方法
Create(c *Context) // 对应 get : path/create 方法
Store(c *Context) // 对应 post : path 方法
Update(c *Context) // 对应put/patch : path/:id 方法
Edit(c *Context) // 对应get : path/:id/edit
Show(c *Context) // 对应 get: route/:id
Destroy(c *Context) // 对应 delete: route/:id
}

// 默认基本控制器
type Controller struct {
}

func (cc *Controller) Index(c *Context) {

}

func (cc *Controller) Create(c *Context) {

}

func (cc *Controller) Store(c *Context) {

}

func (cc *Controller) Update(c *Context) {

}

func (cc *Controller) Edit(c *Context) {

}
func (cc *Controller) Show(c *Context) {

}

func (cc *Controller) Destroy(c *Context) {

}
79 changes: 47 additions & 32 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
package main

import (
"fmt"
"github.com/silsuer/bingo-router"
"net/http"
)

// 定义
func setRoute() *bingo_router.Route {
return bingo_router.NewRoute().Prefix("/common").Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
fmt.Fprintln(c.Writer, "common middleware 1")
next(c)
}).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
fmt.Fprintln(c.Writer, "common middleware 2")
next(c)
}).Mount(func(b *bingo_router.Builder) {
b.NewRoute().Get("/test1").Target(func(c *bingo_router.Context) {
fmt.Fprint(c.Writer, "hello test 1")
}).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
next(c)
fmt.Fprintln(c.Writer, " middleware test 1")

})

b.NewRoute().Get("/test2").Target(func(c *bingo_router.Context) {
fmt.Fprint(c.Writer, "hello test2")
}).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
next(c)
fmt.Fprintln(c.Writer, "test 2 middleware 1")

}).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
fmt.Fprintln(c.Writer, "test 2 middleware 2")
next(c)
})
})
}
//// 定义
//func setRoute() *bingo_router.Route {
// return bingo_router.NewRoute().Prefix("/common").Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// fmt.Fprintln(c.Writer, "common middleware 1")
// next(c)
// }).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// fmt.Fprintln(c.Writer, "common middleware 2")
// next(c)
// }).Mount(func(b *bingo_router.Builder) {
// b.NewRoute().Get("/test1").Target(func(c *bingo_router.Context) {
// fmt.Fprint(c.Writer, "hello test 1")
// }).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// next(c)
// fmt.Fprintln(c.Writer, " middleware test 1")
//
// })
//
// b.NewRoute().Get("/test2").Target(func(c *bingo_router.Context) {
// fmt.Fprint(c.Writer, "hello test2")
// }).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// next(c)
// fmt.Fprintln(c.Writer, "test 2 middleware 1")
//
// }).Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// fmt.Fprintln(c.Writer, "test 2 middleware 2")
// next(c)
// })
// })
//}

func main() {
// 创建一个路由
r := bingo_router.New()

// 得到一个路由
rr := setRoute()
//rr := setRoute()

//r2 := bingo_router.NewRoute().Get("/test").Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
// fmt.Fprint(c.Writer,"middleware")
Expand All @@ -50,10 +49,26 @@ func main() {
// fmt.Fprintln(c.Writer,"target")
//})
// 挂载路由方法,遍历传入的所有路由,然后遍历每个路由里的子路由,并设定路径等,设定中间件等
r.Mount(rr)
//r.Mount(rr)

// 按照列表打印所有路由

// 使用控制器一次性挂载多个路由
r.Mount(bingo_router.NewRoute().Resource("/resource", &controller{}))
// 启动服务
r.PrintRoutes()
http.ListenAndServe(":8080", r)

// TODO 服务的平滑重启和关闭
}

type controller struct {
bingo_router.Controller
}

func (cc *controller) Index(c *bingo_router.Context) {
//c.Redirect("/get")
m := make(map[string]int)
m["id"] = 111
c.ResponseJson(&m)
}
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/silsuer/bingo-router

require (
github.com/json-iterator/go v1.1.5 // indirect
github.com/julienschmidt/httprouter v1.2.0
github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44
github.com/klauspost/cpuid v1.2.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/modood/table v0.0.0-20181112072225-499dc7fba710
github.com/valyala/bytebufferpool v0.0.0-20180905182247-cdfbe9377474
github.com/valyala/fasthttp v0.0.0-20171207120941-e5f51c11919d
)
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modood/table v0.0.0-20181112072225-499dc7fba710 h1:KkTJhLbA/nYDXBQZp9aRiBLAQ6LmcyV7v57vlCuCa94=
github.com/modood/table v0.0.0-20181112072225-499dc7fba710/go.mod h1:41qyXVI5QH9/ObyPj27CGCVau5v/njfc3Gjj7yzr0HQ=
github.com/valyala/bytebufferpool v0.0.0-20180905182247-cdfbe9377474/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v0.0.0-20171207120941-e5f51c11919d/go.mod h1:+g/po7GqyG5E+1CNgquiIxJnsXEi5vwFn5weFujbO78=
72 changes: 60 additions & 12 deletions route.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package bingo_router

import "net/http"
import (
"strings"
"runtime"
"reflect"
)

const GET = "GET"
const POST = "POST"
const DELETE = "DELETE"
const PUT = "PUT"
const PATCH = "PATCH"

// 上下文结构体
type Context struct {
Writer http.ResponseWriter // 响应
Request *http.Request // 请求
Params Params //参数
//Session Session // 保存session
}

// 路由
type Route struct {
path string // 路径
Expand Down Expand Up @@ -63,31 +59,49 @@ func (r *Route) Post(path string) *Route {
}

// 添加路由时需要,设置为put方法
func (r *Route) Put(path string, target TargetHandle) *Route {
func (r *Route) Put(path string) *Route {
//return r.Request(PUT, path, target)
r.path = path
r.method = PUT
return r
}

// 添加路由时需要,设置为patch方法
func (r *Route) Patch(path string, target TargetHandle) *Route {
func (r *Route) Patch(path string) *Route {
//return r.Request(PATCH, path, target)
r.path = path
r.method = PATCH
return r
}

// 添加路由时需要,设置为delete方法
func (r *Route) Delete(path string, target TargetHandle) *Route {
func (r *Route) Delete(path string) *Route {
//return r.Request(DELETE, path, target)
r.path = path
r.method = DELETE
return r
}

// 传入一个控制器,自动构建多个路由
func (r *Route) Resource(path string, controller IController) *Route {
// 在当前路由下挂载子路由
r.Mount(func(b *Builder) {
b.NewRoute().Get(path).Target(controller.Index)
b.NewRoute().Get(path + "/detail/:id").Target(controller.Show)
b.NewRoute().Post(path).Target(controller.Store)
b.NewRoute().Get(path + "/create").Target(controller.Create)
b.NewRoute().Put(path + "/:id").Target(controller.Update)
b.NewRoute().Patch(path + "/:id").Target(controller.Update)
b.NewRoute().Get(path + "/edit/:id").Target(controller.Edit)
b.NewRoute().Delete(path + "/:id").Target(controller.Destroy)
})
return r
}

// 这里传入一个回调
func (r *Route) Target(target TargetHandle) *Route {
r.name = r.path + "." + r.method

return r.Request(r.method, r.path, target)
}

Expand Down Expand Up @@ -116,6 +130,14 @@ func (r *Route) MiddlewareGroup(hg []MiddlewareHandle) *Route {
return r
}

func (r *Route) Name(name string) *Route {
if r.name != "" {
return r
}
r.name = name
return r
}

// 挂载子路由,这里只是将回调中的路由放入
func (r *Route) Mount(rr func(b *Builder)) *Route {
builder := new(Builder)
Expand All @@ -127,4 +149,30 @@ func (r *Route) Mount(rr func(b *Builder)) *Route {
return r
}

func (r *Route) print(arr []Output) []Output {
o := Output{}
o.Name = r.name
o.URI = r.path
o.Method = r.method
o.Middleware = strings.Join(r.printMiddlewares(), "|")
o.Action = runtime.FuncForPC(reflect.ValueOf(r.targetMethod).Pointer()).Name()
arr = append(arr, o)
if len(r.mount) > 0 {
for rr := range r.mount {
arr = r.mount[rr].print(arr)
}
}

return arr
}

// 返回所有的中间件名称组合成的数组
func (r *Route) printMiddlewares() []string {
var res []string
for m := range r.middleware {
res = append(res, runtime.FuncForPC(reflect.ValueOf(r.middleware[m]).Pointer()).Name())
}
return res
}

// 每个请求进来都要生成一个管道,根据管道执行中间件最后到达目的路由
28 changes: 27 additions & 1 deletion router.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"
"strings"
"strconv"
"github.com/modood/table"
)

type Handle func(http.ResponseWriter, *http.Request, Params)
Expand Down Expand Up @@ -333,7 +334,6 @@ func (r *Router) MountRoute(route *Route) {

// 设置中间件
//setRouteMiddlewares(currentPointer, route)

if route.method != "" && p != "" {
r.Handle(route.method, p, route)
}
Expand Down Expand Up @@ -380,3 +380,29 @@ func setMiddlewares(current int, route *Route) {
}
}
}

type Output struct {
Method string
URI string
Name string
Action string
Middleware string
}

// 在控制台中打印所有路由
func (r *Router) PrintRoutes() {
var outputs []Output
// 遍历所有路由,拼接成table结构体,然后打印输出
for m := range r.trees {
rr := r.trees[m].route
if rr.path == "" {
continue
}

// 调用路由的一个方法,传入一个 output数组,如果有
outputs = append(outputs, rr.print(outputs)...)
}

//fmt.Println(outputs)
table.Output(outputs)
}

0 comments on commit c9ccb02

Please sign in to comment.