https://github.com/welllog/golt
https://github.com/welllog/golt
Last synced: 11 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/welllog/golt
- Owner: welllog
- License: apache-2.0
- Created: 2023-12-15T08:23:57.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-03-18T03:35:24.000Z (about 2 years ago)
- Last Synced: 2025-01-18T05:42:45.274Z (over 1 year ago)
- Language: Go
- Size: 33.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README-CN.md
- License: LICENSE
Awesome Lists containing this project
README
English | 中文
# golt
一个简单的http api开发工具库,尝试做到区别于Go标准http库的开发方式,在api开发上更简洁、易用
### srvhttp库
#### http handler
Go http标准库及其它常用库
```
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]string{"hello": "world"})
})
```
golt
```
engine := srvhttp.New()
engine.Any("/hello", func(ctx *srvhttp.Context) (any, error) {
return map[string]string{"hello": "world"}, nil
})
// Output:
// {"data":{"hello":"world"}}
engine.POST("/error", func(ctx *Context) (any, error) {
return nil, unierr.New(1000, "test error").WithData(map[string]int{"reason": 20})
})
// Output:
// {"code":1000,"msg":"test error","data":{"reason":20}}
```
#### http middleware
常见http路由中间件
```
middleware.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
next.ServeHTTP(writer, request)
})
})
```
golt
```
engine.Use(func(ctx *srvhttp.Context, next srvhttp.Handler) (any, error) {
ret, err := next(ctx)
if err != nil {
// todo
}
return ret, nil
})
```
### srvhttp 使用概览
```
// 初始化一个http engine
engine := srvhttp.New()
// 添加路由
user := engine.Group("/user")
user.POST("/login", loginHandler)
user.PATCH("/info", infoHandler)
user.Use(authMiddleware)
engine.GET("/index", indexHandler)
engine.Sub().GET("/index/menu", menuhandler)
engine.Sub().GET("/index/articles/{category}/{id:[0-9]+}", articleHandler)
engine.Static("/static", "./static", false)
// 跨域
engine.UseCors(srvhttp.CorsConfig{
AllowPrivateNetwork: true,
AllowCredentials: true,
AllowOrigins: []string{"*127.0.0.1", "https://172.10.0.4"},
AllowMethods: []string{"*"},
AllowHeaders: []string{"*"},
MaxAge: 12 * time.Hour,
})
srv := http.Server{
Addr: "0.0.0.0:8080",
Handler: engine,
}
srv.ListenAndServe()
```
自定义响应处理函数
```
engine := srvhttp.New(
srvhttp.WithResponseFunc(func(response any, err error, c *srvhttp.Context) {
if err != nil {
c.WriteHeader(http.StatusBadRequest)
c.Write([]byte(err.Error()))
return
}
json.NewEncoder(c).Encode(response)
}),
)
```
如果在http handler中需要返回特定数据而不使用通用响应函数,可以像使用http.ResponseWriter一样直接使用srvhttp.Context
```
engine.Any("/hello", func(ctx *srvhttp.Context) (any, error) {
ctx.WriteHeader(http.StatusOK)
ctx.Write([]byte("hello world"))
// 返回值会被中间件捕捉,如果此处返回nil,则后续中间件将拿不到结果
return nil, nil
})
engine.Any("/page", func(ctx *srvhttp.Context) (any, error) {
ctx.WriteHeader(http.StatusOK)
ctx.Write([]byte("
hello world
"))
// 此处返回的值将不再出现在响应结果中,返回的错误同理,但仍会被中间获取到
return "ok", nil
})
```
### config 库
golt的config库提供了统一的配置管理,支持从文件、etcd加载配置,支持动态加载配置,支持配置更新通知。
其读取源需要一个额外的文件配置,config.FromFile("config.yaml"),其中config.yaml中指定了读取配置的源以及映射方式
#### 从文件加载配置
从文件读取配置的
```yaml
# 加载配置的源为文件系统
- source: file://
configs:
# 命名空间,决定了该配置从哪个文件中读取
- namespace: test/demo1 | test/demo2
# 命名空间指向的文件
path: test1.yaml
# 是否监听该文件变动来动态加载配置
dynamic: true
```
#### 从etcd加载配置
```yaml
# 加载配置的源为etcd以及地址
- source: etcd://127.0.0.1:2379
configs:
# 命名空间,决定了该配置从哪个etcd及其key path中读取
- namespace: test/demo4
# 当前etcd下的key path
path: /v1/test/demo4/
# 是否监听该key path变动来动态加载配置
dynamic: true
```
#### 从自定义etcd客户端加载配置
```yaml
# 加载配置的源为自定义etcd客户端
- source: custom_etcd://
configs:
# 命名空间,决定了该配置从哪个etcd及其key path中读取
- namespace: test/demo4
# 当前etcd下的key path
path: /v1/test/demo4/
# 是否监听该key path变动来动态加载配置
dynamic: true
```
#### config使用概览
```
c, err := FromFile("./config.yaml")
if err != nil {
panic(err)
}
defer c.Close()
c.String("test/demo1", "app_name")
c.Int64("test/demo2", "retry")
c.Int("test/demo2", "retry")
c.Float64("test/demo4", "rate")
c.Bool("test/demo4", "enable")
c.YamlDecode("test/demo1", "log", &logConf)
c.JsonDecode("test/demo4", "data", &data)
c.Decode("test/demo4", "data", &data, json.Unmarshal)
c.GetRaw("test/demo1", "app_name")
c.UnsafeGetRaw("test/demo1", "app_name")
c.GetRawString("test/demo1", "app_name")
c.OnKeyChange("test/demo1", "app_name", func([]byte) error) {
// do something
}
```