Fun是一个现代化的实时应用框架,专为构建基于Web的后端服务而设计。它提供了一套简洁而强大的工具,帮助开发者快速构建具有实时通信功能的应用程序。
- 🚀 基于 Gorilla WebSocket 构建
- 🔧 自动依赖注入
- 🛡️ 参数验证(集成 validator.v10)
- 📝 多级别日志系统(支持文件和终端输出)
- 🔄 WebSocket 心跳检测和连接管理
- 🎯 自动生成 TypeScript 客户端代码
- 🧪 内置测试工具
- 🛡️ 守卫机制(类似中间件)
- 📦 结构化响应格式
- 🧭 枚举类型支持
go get github.com/fun-go/fun创建 main.go:
package main
import (
"github.com/fun-go/fun"
)
// 定义服务结构体
type HelloService struct {
fun.Ctx // 必须嵌入 Ctx
}
// 定义 DTO
type HelloDto struct {
Name string
}
// 定义方法
func (s *HelloService) Hello(dto HelloDto) string {
return "Hello, " + dto.Name
}
func main() {
// 绑定服务
fun.BindService(HelloService{})
// 启动服务
fun.Start(3000)
}go run main.go服务将在端口 3000 上启动。
// 在 main.go 中添加
fun.Gen()运行后,TypeScript 代码将生成在 ../gen/ts/ 目录下,复制到前端项目中。
import fun from "./server/fun";
// 创建客户端实例
const client = fun.create("ws://localhost:3000");
// 调用服务方法
const result = await client.helloService.hello({ name: "World" });
console.log(result); // "Hello, World"服务是包含业务逻辑的结构体,必须嵌入 [fun.Ctx]:
type UserService struct {
fun.Ctx // 提供上下文信息
// 其他依赖...
}服务中的公开方法会自动暴露为 WebSocket 接口:
func (s *UserService) GetUser(dto UserDto) *User {
// 业务逻辑
return &User{Name: dto.Name}
}用于传递参数的对象,支持参数验证:
type UserDto struct {
Name string
Email string `validate:"email"`
Age int `validate:"min=0,max=150"`
}Fun 框架支持生成 TypeScript 枚举类型。要使用此功能,需要定义 uint8 类型并实现 enum 或 displayEnum 接口:
// 实现 enum 接口
type Status uint8
func (s Status) Names() []string {
return []string{
"Active",
"Inactive",
}
}// 实现 displayEnum 接口
type UserStatus uint8
func (s UserStatus) Names() []string {
return []string{
"Active",
"Inactive",
"Pending",
}
}
func (s UserStatus) DisplayNames() []string {
return []string{
"已激活",
"未激活",
"待审核",
}
}生成的 TypeScript 代码:
enum userStatus {
Active,
Inactive,
Pending,
}
export function userStatusDisplayName(value:userStatus): string {
switch (value) {
case userStatus.Active:
return '已激活';
case userStatus.Inactive:
return '未激活';
case userStatus.Pending:
return '待审核';
default:
return "未知";
}
}
export default userStatus使用 fun.Wired[T]() 进行依赖注入:
type Repository struct {
// 数据库连接等
}
func (r *Repository) New() {
// 初始化逻辑
}
type UserService struct {
fun.Ctx
Repo *Repository // 自动注入
}类似中间件,用于请求前的处理:
type AuthGuard struct {
// 依赖...
}
func (g *AuthGuard) Guard(ctx fun.Ctx) {
// 鉴权逻辑
// 失败时可以 panic 错误
}
// 绑定全局守卫
fun.BindGuard(AuthGuard{})
// 或绑定服务级守卫
fun.BindService(UserService{}, AuthGuard{})支持长连接模式,服务端可以主动推送数据:
func (s *UserService) Subscribe(dto SubscribeDto, close fun.ProxyClose) *chan string {
ch := make(chan string)
// 处理关闭回调
close(func() {
close(ch)
})
go func() {
for {
select {
case msg := <-ch:
s.Push(s.Id, s.RequestId, msg) // 推送数据
}
}
}()
return &ch
}// 配置日志
logger := &fun.Logger{
Level: fun.InfoLevel,
Mode: fun.FileMode,
MaxSizeFile: 10, // 10MB
MaxNumberFiles: 100, // 最多100个文件
ExpireLogsDays: 7, // 保留7天
}
fun.ConfigLogger(logger)
// 使用日志
fun.InfoLogger("服务启动成功")
fun.ErrorLogger("发生错误", err)集成 validator.v10,支持自定义验证规则:
// 绑定自定义验证规则
fun.BindValidate("custom", func(fl validator.FieldLevel) bool {
// 自定义验证逻辑
return true
})
// 在 DTO 中使用
type CustomDto struct {
Field string `validate:"custom"`
}提供完整的测试工具:
func TestHelloService(t *testing.T) {
// 创建请求
request := fun.GetRequestInfo(t, HelloService{}, "Hello", HelloDto{Name: "World"}, nil)
// 发起请求
result := fun.MockRequest[string](t, request)
// 验证结果
if *result.Data != "Hello, World" {
t.Errorf("期望 'Hello, World', 得到 '%s'", *result.Data)
}
}// 启动 HTTP 服务
fun.Start(3000)
// 启动 HTTPS 服务
fun.StartTls("cert.pem", "key.pem", 3000)type Logger struct {
Level uint8 // 日志级别
Mode uint8 // 输出模式 (TerminalMode/FileMode)
MaxSizeFile uint8 // 文件最大大小(MB)
MaxNumberFiles uint64 // 文件最多数量
ExpireLogsDays uint8 // 文件保留时间(天)
}欢迎提交 Issue 和 Pull Request!