feat: add nft(nf_util) package: resp(wrap status, data, msg ...); add config: enable_not_impled_handler(default return 501 not impled)
This commit is contained in:
parent
7b62a82b42
commit
79e94dfd21
21
group.go
21
group.go
@ -1,6 +1,7 @@
|
|||||||
package nf
|
package nf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -25,8 +26,26 @@ func (group *RouterGroup) Group(prefix string) *RouterGroup {
|
|||||||
return newGroup
|
return newGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (group *RouterGroup) verifyHandlers(path string, handlers ...HandlerFunc) []HandlerFunc {
|
||||||
|
if len(handlers) == 0 {
|
||||||
|
if !group.app.config.EnableNotImplementHandler {
|
||||||
|
panic(fmt.Sprintf("missing handler in route: %s", path))
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers = append(handlers, ToDoHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, handler := range handlers {
|
||||||
|
if handler == nil {
|
||||||
|
panic(fmt.Sprintf("nil handler found in route: %s", path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handlers
|
||||||
|
}
|
||||||
|
|
||||||
func (group *RouterGroup) addRoute(method string, comp string, handlers ...HandlerFunc) {
|
func (group *RouterGroup) addRoute(method string, comp string, handlers ...HandlerFunc) {
|
||||||
verifyHandlers(comp, handlers...)
|
handlers = group.verifyHandlers(comp, handlers...)
|
||||||
pattern := group.prefix + comp
|
pattern := group.prefix + comp
|
||||||
log.Printf("Add Route %4s - %s", method, pattern)
|
log.Printf("Add Route %4s - %s", method, pattern)
|
||||||
group.app.router.addRoute(method, pattern, handlers...)
|
group.app.router.addRoute(method, pattern, handlers...)
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
package nf
|
package nf
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type HandlerFunc func(*Ctx) error
|
type HandlerFunc func(*Ctx) error
|
||||||
|
|
||||||
|
func ToDoHandler(c *Ctx) error {
|
||||||
|
return c.Status(501).SendString(fmt.Sprintf("%s - %s Not Implemented", c.Method, c.Path()))
|
||||||
|
}
|
||||||
|
3
nf.go
3
nf.go
@ -19,7 +19,8 @@ type Config struct {
|
|||||||
DisableRecover bool `json:"-"`
|
DisableRecover bool `json:"-"`
|
||||||
DisableHttpErrorLog bool `json:"-"`
|
DisableHttpErrorLog bool `json:"-"`
|
||||||
|
|
||||||
NotFoundHandler HandlerFunc `json:"-"`
|
EnableNotImplementHandler bool `json:"-"`
|
||||||
|
NotFoundHandler HandlerFunc `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
70
nft/resp/error.go
Normal file
70
nft/resp/error.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package resp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/loveuer/nf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
status uint32
|
||||||
|
msg string
|
||||||
|
err error
|
||||||
|
data any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
if e.msg != "" {
|
||||||
|
return fmt.Sprintf("%s: %s", e.msg, e.err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
switch e.status {
|
||||||
|
case 200:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG200, e.err.Error())
|
||||||
|
case 202:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG202, e.err.Error())
|
||||||
|
case 400:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG400, e.err.Error())
|
||||||
|
case 401:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG401, e.err.Error())
|
||||||
|
case 403:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG403, e.err.Error())
|
||||||
|
case 404:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG404, e.err.Error())
|
||||||
|
case 429:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG429, e.err.Error())
|
||||||
|
case 500:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG500, e.err.Error())
|
||||||
|
case 501:
|
||||||
|
return fmt.Sprintf("%s: %s", MSG501, e.err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.err.Error()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewError(statusCode uint32, msg string, rawErr error, data any) Error {
|
||||||
|
return Error{
|
||||||
|
status: statusCode,
|
||||||
|
msg: msg,
|
||||||
|
err: rawErr,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RespError(c *nf.Ctx, err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return Resp(c, 500, MSG500, "response with nil error", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var re = &Error{}
|
||||||
|
if errors.As(err, re) {
|
||||||
|
if re.err == nil {
|
||||||
|
return Resp(c, re.status, re.msg, re.msg, re.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, re.status, re.msg, re.err.Error(), re.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 500, MSG500, err.Error(), nil)
|
||||||
|
}
|
127
nft/resp/resp.go
Normal file
127
nft/resp/resp.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package resp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/loveuer/nf"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleEmptyMsg(status uint32, msg string) string {
|
||||||
|
if msg == "" {
|
||||||
|
switch status {
|
||||||
|
case 200:
|
||||||
|
msg = MSG200
|
||||||
|
case 202:
|
||||||
|
msg = MSG202
|
||||||
|
case 400:
|
||||||
|
msg = MSG400
|
||||||
|
case 401:
|
||||||
|
msg = MSG401
|
||||||
|
case 403:
|
||||||
|
msg = MSG403
|
||||||
|
case 404:
|
||||||
|
msg = MSG404
|
||||||
|
case 429:
|
||||||
|
msg = MSG429
|
||||||
|
case 500:
|
||||||
|
msg = MSG500
|
||||||
|
case 501:
|
||||||
|
msg = MSG501
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp(c *nf.Ctx, status uint32, msg string, err string, data any) error {
|
||||||
|
msg = handleEmptyMsg(status, msg)
|
||||||
|
|
||||||
|
c.Set(RealStatusHeader, strconv.Itoa(int(status)))
|
||||||
|
|
||||||
|
if data == nil {
|
||||||
|
return c.JSON(nf.Map{"status": status, "msg": msg, "err": err})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nf.Map{"status": status, "msg": msg, "err": err, "data": data})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp200(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG200
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 200, msg, "", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp202(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG202
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 202, msg, "", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp400(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG400
|
||||||
|
err := ""
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
err = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 400, msg, err, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp401(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG401
|
||||||
|
err := ""
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
err = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 401, msg, err, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp403(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG403
|
||||||
|
err := ""
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
err = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 403, msg, err, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp429(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG429
|
||||||
|
err := ""
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
err = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 429, msg, err, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp500(c *nf.Ctx, data any, msgs ...string) error {
|
||||||
|
msg := MSG500
|
||||||
|
err := ""
|
||||||
|
|
||||||
|
if len(msgs) > 0 && msgs[0] != "" {
|
||||||
|
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
|
||||||
|
err = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return Resp(c, 500, msg, err, data)
|
||||||
|
}
|
17
nft/resp/var.go
Normal file
17
nft/resp/var.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package resp
|
||||||
|
|
||||||
|
const (
|
||||||
|
MSG200 = "请求成功"
|
||||||
|
MSG202 = "请求成功, 请稍后..."
|
||||||
|
MSG400 = "请求参数错误"
|
||||||
|
MSG401 = "登录已过期, 请重新登录"
|
||||||
|
MSG403 = "请求权限不足"
|
||||||
|
MSG404 = "请求资源未找到"
|
||||||
|
MSG429 = "请求过于频繁, 请稍后再试"
|
||||||
|
MSG500 = "服务器开小差了, 请稍后再试"
|
||||||
|
MSG501 = "功能开发中, 尽情期待"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RealStatusHeader = "NF-STATUS"
|
||||||
|
)
|
12
util.go
12
util.go
@ -27,18 +27,6 @@ const (
|
|||||||
MIMEApplicationJavaScriptCharsetUTF8 = "application/javascript; charset=utf-8"
|
MIMEApplicationJavaScriptCharsetUTF8 = "application/javascript; charset=utf-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
func verifyHandlers(path string, handlers ...HandlerFunc) {
|
|
||||||
if len(handlers) == 0 {
|
|
||||||
panic(fmt.Sprintf("missing handler in route: %s", path))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, handler := range handlers {
|
|
||||||
if handler == nil {
|
|
||||||
panic(fmt.Sprintf("nil handler found in route: %s", path))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseVendorSpecificContentType check if content type is vendor specific and
|
// parseVendorSpecificContentType check if content type is vendor specific and
|
||||||
// if it is parsable to any known types. If it's not vendor specific then returns
|
// if it is parsable to any known types. If it's not vendor specific then returns
|
||||||
// the original content type.
|
// the original content type.
|
||||||
|
@ -1,2 +1,6 @@
|
|||||||
### basic - get
|
### basic - get
|
||||||
GET http://127.0.0.1/hello/nf
|
GET http://127.0.0.1/hello/nf
|
||||||
|
|
||||||
|
|
||||||
|
### test resp error
|
||||||
|
GET http://127.0.0.1/error
|
@ -1,24 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/loveuer/nf"
|
"github.com/loveuer/nf"
|
||||||
|
"github.com/loveuer/nf/nft/resp"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := nf.New()
|
app := nf.New(nf.Config{EnableNotImplementHandler: true})
|
||||||
|
|
||||||
app.Get("/hello/:name", func(c *nf.Ctx) error {
|
app.Get("/hello/:name", func(c *nf.Ctx) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
return c.JSON(nf.Map{"status": 200, "data": "hello, " + name})
|
return c.JSON(nf.Map{"status": 200, "data": "hello, " + name})
|
||||||
})
|
})
|
||||||
|
app.Get("/not_impl")
|
||||||
app.Patch("/world", func(c *nf.Ctx) error {
|
app.Patch("/world", func(c *nf.Ctx) error {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
c.Status(404)
|
c.Status(404)
|
||||||
return c.JSON(nf.Map{"method": c.Method, "status": c.StatusCode})
|
return c.JSON(nf.Map{"method": c.Method, "status": c.StatusCode})
|
||||||
})
|
})
|
||||||
|
app.Get("/error", func(c *nf.Ctx) error {
|
||||||
|
return resp.RespError(c, resp.NewError(404, "not found", errors.New("NNNot Found"), nil))
|
||||||
|
})
|
||||||
|
|
||||||
ln, _ := net.Listen("tcp", ":80")
|
ln, _ := net.Listen("tcp", ":80")
|
||||||
log.Fatal(app.RunListener(ln))
|
log.Fatal(app.RunListener(ln))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user