Apiware HTTP接口定义与请求参数绑定中间件 项目简介
Apiware 将 Go 语言 net/http 及 fasthttp 请求的指定参数绑定到结构体,并验证参数值的合法性。 建议您可以使用结构体作为 web 框架的 Handler,并用该中间件快速绑定请求参数,节省了大量参数类型转换与有效性验证的工作。同时还可以通过该结构体标签,创建 swagger 的 json 配置文件,轻松创建 api 文档服务。Demo 示例 package main
import (
"encoding/json"
"github.com/henrylee2cn/apiware"
// "mime/multipart"
"net/http"
"strings"
)
type TestApiware struct {
Id int `param:"in(path),required,desc(ID),range(1:2)"`
Num float32 `param:"in(query),name(n),range(0.1:10.19)"`
Title string `param:"in(query),nonzero"`
Paragraph []string `param:"in(query),name(p),len(1:10)" regexp:"(^[\\w]*$)"`
Cookie http.Cookie `param:"in(cookie),name(apiwareid)"`
CookieString string `param:"in(cookie),name(apiwareid)"`
// Picture multipart.FileHeader `param:"in(formData),name(pic),maxmb(30)"`
}
var myApiware = apiware.New(pathDecodeFunc, nil, nil)
var pattern = "/test/:id"
func pathDecodeFunc(urlPath, pattern string) apiware.KV {
idx := map[int]string{}
for k, v := range strings.Split(pattern, "/") {
if !strings.HasPrefix(v, ":") {
continue
}
idx[k] = v[1:]
}
pathParams := make(map[string]string, len(idx))
for k, v := range strings.Split(urlPath, "/") {
name, ok := idx[k]
if !ok {
continue
}
pathParams[name] = v
}
return apiware.Map(pathParams)
}
func testHandler(resp http.ResponseWriter, req *http.Request) {
// set cookies
http.SetCookie(resp, &http.Cookie{
Name: "apiwareid",
Value: "http_henrylee2cn",
})
// bind params
params := new(TestApiware)
err := myApiware.Bind(params, req, pattern)
b, _ := json.MarshalIndent(params, "", " ")
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write(append([]byte(err.Error()+"\n"), b...))
} else {
resp.WriteHeader(http.StatusOK)
resp.Write(b)
}
}
func main() {
// Check whether `testHandler` meet the requirements of apiware, and register it
err := myApiware.Register(new(TestApiware))
if err != nil {
panic(err)
}
// server
http.HandleFunc("/test/0", testHandler)
http.HandleFunc("/test/1", testHandler)
http.HandleFunc("/test/1.1", testHandler)
http.HandleFunc("/test/2", testHandler)
http.HandleFunc("/test/3", testHandler)
http.ListenAndServe(":8080", nil)
}
import (
"encoding/json"
"github.com/henrylee2cn/apiware"
// "mime/multipart"
"net/http"
"strings"
)
type TestApiware struct {
Id int `param:"in(path),required,desc(ID),range(1:2)"`
Num float32 `param:"in(query),name(n),range(0.1:10.19)"`
Title string `param:"in(query),nonzero"`
Paragraph []string `param:"in(query),name(p),len(1:10)" regexp:"(^[\\w]*$)"`
Cookie http.Cookie `param:"in(cookie),name(apiwareid)"`
CookieString string `param:"in(cookie),name(apiwareid)"`
// Picture multipart.FileHeader `param:"in(formData),name(pic),maxmb(30)"`
}
var myApiware = apiware.New(pathDecodeFunc, nil, nil)
var pattern = "/test/:id"
func pathDecodeFunc(urlPath, pattern string) apiware.KV {
idx := map[int]string{}
for k, v := range strings.Split(pattern, "/") {
if !strings.HasPrefix(v, ":") {
continue
}
idx[k] = v[1:]
}
pathParams := make(map[string]string, len(idx))
for k, v := range strings.Split(urlPath, "/") {
name, ok := idx[k]
if !ok {
continue
}
pathParams[name] = v
}
return apiware.Map(pathParams)
}
func testHandler(resp http.ResponseWriter, req *http.Request) {
// set cookies
http.SetCookie(resp, &http.Cookie{
Name: "apiwareid",
Value: "http_henrylee2cn",
})
// bind params
params := new(TestApiware)
err := myApiware.Bind(params, req, pattern)
b, _ := json.MarshalIndent(params, "", " ")
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write(append([]byte(err.Error()+"\n"), b...))
} else {
resp.WriteHeader(http.StatusOK)
resp.Write(b)
}
}
func main() {
// Check whether `testHandler` meet the requirements of apiware, and register it
err := myApiware.Register(new(TestApiware))
if err != nil {
panic(err)
}
// server
http.HandleFunc("/test/0", testHandler)
http.HandleFunc("/test/1", testHandler)
http.HandleFunc("/test/1.1", testHandler)
http.HandleFunc("/test/2", testHandler)
http.HandleFunc("/test/3", testHandler)
http.ListenAndServe(":8080", nil)
}