Go-Spring v1.2.0 新增 web 服务器支持,底层路由器基于mux实现,旨在提供更加简单易用的开发体验。
特性:
path/header/cookie/from/body
绑定输入参数支持绑定的函数形式 (将下列函数转换为 http.HandlerFunc ):
友情提示:web 包不依赖 go-spring 容器,可以单独使用 (下方有例子) 😀
Demo 代码:
package main
import (
"context"
"log/slog"
"math/rand"
"mime/multipart"
"net/http"
"time"
"github.com/go-spring-projects/go-spring/gs"
"github.com/go-spring-projects/go-spring/web"
_ "github.com/go-spring-projects/go-spring/web/starter"
)
type Greeting struct {
Logger *slog.Logger `logger:""`
Server *web.Server `autowire:""`
}
func (g *Greeting) OnInit(ctx context.Context) error {
g.Server.Get("/greeting", g.Greeting)
g.Server.Get("/health", g.Health)
g.Server.Post("/user/register/{username}/{password}", g.Register)
g.Server.Post("/user/password", g.UpdatePassword)
return nil
}
func (g *Greeting) Greeting(ctx context.Context) string {
web.FromContext(ctx).
SetCookie("token", "1234567890", 500, "", "", false, false)
return "greeting!!!"
}
func (g *Greeting) Health(ctx context.Context) error {
if 0 == rand.Int()%2 {
return web.Error(400, "health check failed")
}
return nil
}
func (g *Greeting) Register(
ctx context.Context,
req struct {
Username string `path:"username" expr:"len($)>6 && len($)<20"`
Password string `path:"password" expr:"len($)>6 && len($)<20"`
HeadImg *multipart.FileHeader `form:"headImg"`
Captcha string `form:"captcha" expr:"len($)==4"`
UserAgent string `header:"User-Agent"`
Ad string `query:"ad"`
Token string `cookie:"token"`
},
) string {
g.Logger.Info("register user",
slog.String("username", req.Username),
slog.String("password", req.Password),
slog.String("userAgent", req.UserAgent),
slog.String("headImg", req.HeadImg.Filename),
slog.String("captcha", req.Captcha),
slog.String("userAgent", req.UserAgent),
slog.String("ad", req.Ad),
slog.String("token", req.Token),
)
return "ok"
}
func (g *Greeting) UpdatePassword(
ctx context.Context,
req struct {
Password string `json:"password" expr:"len($) > 6 && len($) < 20"` // password
Token string `cookie:"token"` // token
},
) string {
g.Logger.Info("change password", slog.String("password", req.Password))
return "ok"
}
func main() {
gs.Object(new(Greeting))
if err := gs.Run(); nil != err {
panic(err)
}
}
单独使用 web 服务例子:
package main
import (
"context"
"log/slog"
"mime/multipart"
"github.com/go-spring-projects/go-spring/web"
)
func Greeting(ctx context.Context) string {
return "Greeting!!!"
}
func Feedback(
ctx context.Context,
req struct {
Title string `form:"title"` // 反馈标题
Message string `form:"message"` // 反馈说明
Attachments []*multipart.FileHeader `form:"files"` // 上传附件文件列表
EMail string `form:"email"` // 联系邮箱
UserAgent string `header:"User-Agent"` // 浏览器用户代理
},
) string {
slog.Info("received user feedback",
slog.String("title", req.Title),
slog.String("message", req.Message),
slog.String("email", req.EMail),
slog.String("user-Agent", req.UserAgent),
)
//TODO: save feedback to database.
//
return "Thanks for your feedback!!!"
}
func main() {
webSvr := web.NewServer(web.NewRouter(), web.Options{Addr: ":8080"})
webSvr.Get("/greeting", Greeting)
webSvr.Post("/feedback", Feedback)
webSvr.Run()
}
1
8520ccc 343 天前
有木有群 要不要搞个群?有一些想法 可以交流一下
例如 绑定路由这里可以参考 goframe 那样。bind struct 使用 struct 上的方法 同时使用路径进行路由命名 例如 GET /v1/admin/user/fetch 可以是 /v1/admin/下的 v1_admin_user_fetch.go 的文件下面的 由 struct 上的 FetchGET 方法提供 ( goframe 是在 Input 的 struct 上定义这些) 其实这一套实现一个代码生成比较舒服。。。我现在自己搞了一套 但是不是很完善 |
2
8520ccc 343 天前
还有直接绑定 interface
例如绑定 bind(controller.V1()) 这样就可以自动绑定所有 /v1/ 开头的全部路由 (当然前提也是需要提前生成好 V1 这个 interface ) |
3
DefoliationM 343 天前 1
本来挺简单的一些东西,被这么一搞变难用了。
|
4
mightybruce 343 天前
个人观点:非常不喜欢这种被限制的方式, 就算是 aop , 那么也要精简,而不是做全。
让 gin 、echo 、iris 能够接入就行,或者参考 kratos 做成插件形式。 |