support registry and discovery of services
Install
go get -u github.com/axfor/bast
Router
//Person struct
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Addr string `json:"addr"`
}
bast.Get("/xxx", func(ctx *bast.Context) {
//verify imput parameter
err := ctx.Verify("name@required|min:1", "age@required|min:1", "addr/address@required|min:1")
if err != nil {
ctx.Failed(err.Error())
return
}
name := ctx.GetString("name")
age := ctx.GetInt("age")
//handling
//...
person := &Person{
Name: name,
Age: Age,
}
//translator address
person.Addr = ctx.Trans("addr", person.Name)
//handling
//...
ctx.JSON(person)
})
//Person struct
type Person struct {
Name string `json:"name" v:"required|min:1"`
Age int `json:"age" v:"min:1"`
Title string `json:"title"`
}
bast.Post("/xxx", func(ctx *bast.Context) {
person := &Person{}
err := ctx.JSONObj(person)
//or ctx.JSONObj(person,true) //version of verify imput parameter
if err != nil {
ctx.Failed("sorry! invalid parameter")
return
}
person.Age += 2
//translator title
person.Title = ctx.Trans("title", person.Name)
//handling
//...
ctx.JSON(person)
})
bast.Get(/* pattern string */, /* f func(ctx *Context) */)).Auth().Param("test xxx data")
//service registry to etcd
bast.Get(/* pattern string */, /* f func(ctx *Context) */)).Registry("UserAPI")
a similar pipeline validator
key[/key translator][/split divide (default is |)]@verify1[:verify1 param]|verify2
key1@required|int|min:1
key2/key2_translator@required|string|min:1|max:12
key3@sometimes|required|date
note:only is key
//global register keys translator //note:only is key
func init() {
//register keys translator //note:is key
//suck as:verify error
//en: The name field is required
//zh-cn: {0} 不能空
lang.RegisterKeys("zh-cn", map[string]string{
"name": "姓名",
"age": "年龄",
"address": "地址",
})
//other langs
}
note:will continue to add new validator
- date
- int
- ip
- match
- max
- min
- required
- sometimes
httpc is HTTP client library
go get -u github.com/axfor/bast/httpc
result support string,json,xml,yaml,file etc
reqUrl := "https://suggest.taobao.com/sug?code=utf-8&q=phone"
result, err := httpc.Get(reqUrl).String()
if err != nil {
//handling
}
result, err := httpc.Gets("UserAPI").String()
if err != nil {
//handling
}
type tb struct {
Result [][]string `json:"result"`
}
rv := &tb{}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8"
err := httpc.Get(reqUrl).Param("q", "phone").ToJSON(rv)
if err != nil {
//handling
}
type tb struct {
Result [][]string `json:"result"`
}
rv := &tb{}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8"
err := httpc.Get().Param("q", "phone").ToXML(rv)
if err != nil {
//handling
}
type tb struct {
Result [][]string `json:"result"`
}
rv := &tb{}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8"
err := httpc.Get(reqUrl).Param("q", "phone").ToYAML(rv)
if err != nil {
//handling
}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8&q=phone"
err := httpc.Post(reqUrl).ToFile("./files/f.json")
if err != nil {
//handling
}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8&q=phone"
result, err := httpc.Post(reqUrl).File("testFile", "./files/f.json").String()
if err != nil {
//handling
}
reqUrl := "https://suggest.taobao.com/sug?code=utf-8&q=phone"
result, err := httpc.Post(reqUrl).MarkTag("ai").String()
if err != nil {
//handling
}
Global register hook Before and After
func init() {
httpc.Before(func(c *httpc.Client) error {
if c.Tag == "ai" {
c.Header("xxxx-test-header", "httpc")
} else {
//others handling
}
return nil
})
httpc.After(func(c *httpc.Client) {
if c.Tag == "ai" && c.OK() {
//log..
} else {
//others handling
}
})
}
bast.Run(":9999")
like nginx commandline
./Ai -h
Run in background
./Ai --start
stop program
./Ai --stop
graceful restart. stop and start
./Ai --reload
seting config files.(default is ./config.conf)
./Ai --conf=your path/config.conf
installed as service.(daemon)
./Ai --install
uninstall a service.(daemon)
./Ai --uninstall
migration or initial system(handle sql script ...)
./Ai --migration
run program (run in background)
./Ai --start --conf=./config.conf
deploy program (startup)
./Ai --install
support multiple instances
[
{//a instance
"key":"xxx-conf",
"name":"xx",
"addr":":9999",
"fileDir":"./file/",//(default is ./file/)
"debug":false,
"baseUrl":"",
"idNode":0,
"lang":"en",//default lang en,zh-cn
"trans":"",//translator files or dir
"sameSite":"none",//cookie sameSite strict、lax、none
"wrap":true,//wrap response body
"session":{//session conf
"enable":false,
"lifeTime":20,
"name":"_sid",//session name
"prefix":"",//session id prefix
"suffix":"",//session id suffix
"engine":"memory",//session engine memory、redis、redis-cluster
"source":"cookie",//cookie、header
"sessionLock":false,///each session a lock(default is false)
"redis":{//if source eq redis or redis-cluster
"addrs":"ip:port,ip2:port2",
"password":"",
"poolSize":0
}
},
"log":{
"outPath":"./logs/logs.log", //(default is ./logs/logs.log)
"level":"debug",
"maxSize":10,
"maxBackups":3,
"maxAge":28,
"debug":false,
"logSelect":false
},
"cors":{//CORS https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
"allowOrigin":"",
"allowMethods":"GET, POST, OPTIONS, PATCH, PUT, DELETE, HEAD,UPDATE",
"allowHeaders":"",
"maxAge":"1728000",
"allowCredentials":"true"
},
"page":{
"page":"page name",
"total":"total name",
"pageRow":"pageRow name"
},
"conf":{//user config(non bast framework) such as db config
"key":"app",
"name":"xxx",
"dbTitle":"xxx app",
"dbName":"xxxx db",
"dbUser":"xxx",
"dbPwd":"******",
"dbServer":"localhost"
//..more field..//
},
"registry":{ //service registry to etcd
"enable":true,
"baseUrl":"http://127.0.0.1:9999/",
"prefix":"bast/",
"endpoints":"http://127.0.0.1:2379"
},
"discovery":{//service discovery from etcd
"enable":true,
"prefix":"bast/",
"endpoints":"http://127.0.0.1:2379"
},
"extend":"",//user extend
"shutdown":60000,
}
//..more instances..//
]
use
id := bast.ID()
fmt.Printf("id=%d", id)
benchmark test
go test -bench=. -benchmem ./ids
physics cpu4
go test -bench=. -benchmem ./ids
goos: darwin
goarch: amd64
Benchmark_ID-4 20000000 72.1 ns/op 16 B/op 1 allocs/op
Benchmark_Parallel_ID-4 10000000 150 ns/op 16 B/op 1 allocs/op
PASS
ok github.com/axfor/bast/ids 10.126s