web

package
v1.0.0-alpha.25 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2026 License: MIT Imports: 21 Imported by: 0

README

Web 框架

← 返回主目录

CSGO Web 框架基于 Gin,提供了现代化的 Web 应用开发体验,包括路由、控制器、中间件、请求验证等完整功能。

特性

  • ✅ 简洁的应用构建器(WebApplicationBuilder)
  • ✅ HttpContext 和 ActionResult 模式
  • ✅ 类型安全的路由系统
  • ✅ 控制器模式支持
  • ✅ 中间件管道
  • ✅ 自动请求验证
  • ✅ 统一的 API 响应格式
  • ✅ CORS 支持
  • ✅ 静态文件服务
  • ✅ 依赖注入集成

快速开始

1. 创建第一个应用
package main

import (
    "github.com/gocrud/csgo/web"
)

func main() {
    // 创建应用构建器
    builder := web.CreateBuilder()
    
    // 构建应用
    app := builder.Build()
    
    // 定义路由
    app.MapGet("/", func(c *web.HttpContext) web.IActionResult {
        return c.Ok(web.M{"message": "Hello, CSGO!"})
    })
    
    // 运行应用
    app.Run()  // 默认监听 :8080
}
2. 使用依赖注入
// 定义服务
type UserService struct{}

func NewUserService() *UserService {
    return &UserService{}
}

func (s *UserService) GetUser(id int) string {
    return fmt.Sprintf("User %d", id)
}

func main() {
    builder := web.CreateBuilder()
    
    // 注册服务
    builder.Services.Add(NewUserService)
    
    app := builder.Build()
    
    // 在路由中使用服务
    app.MapGet("/users/:id", func(c *web.HttpContext) web.IActionResult {
        userService := di.Get[*UserService](c.Services)
        id, err := web.Path[int](c, "id").Value()
        if err != nil {
            return err
        }
        user := userService.GetUser(id)
        return c.Ok(web.M{"user": user})
    })
    
    app.Run()
}
3. 使用控制器
type UserController struct {
    userService *UserService
}

func NewUserController(userService *UserService) *UserController {
    return &UserController{userService: userService}
}

func (ctrl *UserController) GetUser(c *web.HttpContext) web.IActionResult {
    id, err := web.Path[int](c, "id").Value()
    if err != nil {
        return err
    }
    user := ctrl.userService.GetUser(id)
    return c.Ok(user)
}

// 在 main 中注册
builder := web.CreateBuilder()
builder.Services.Add(NewUserService)
web.AddController(builder.Services, NewUserController)

app := builder.Build()
app.MapControllers()
app.Run()

WebApplicationBuilder

创建构建器
// 创建默认构建器
builder := web.CreateBuilder()

// 传入命令行参数
builder := web.CreateBuilder(os.Args[1:]...)

构建器会自动:

  • 加载配置(appsettings.json)
  • 设置环境(Development/Production)
  • 注册基础服务(日志、配置等)
  • 初始化依赖注入容器
配置服务
builder := web.CreateBuilder()

// 注册服务
builder.Services.Add(NewUserService)
builder.Services.Add(NewOrderService)

// 注册配置选项
var dbConfig DatabaseConfig
builder.Configuration.Bind("database", &dbConfig)
builder.Services.AddInstance(&dbConfig)
配置主机
builder := web.CreateBuilder()

// 配置监听地址
builder.WebHost.UseUrls("http://localhost:5000")

// 配置关闭超时
builder.WebHost.UseShutdownTimeout(30)
访问配置和环境
builder := web.CreateBuilder()

// 访问配置
port := builder.Configuration.GetInt("server:port", 8080)
dbConn := builder.Configuration.Get("database:connection")

// 访问环境
if builder.Environment.IsDevelopment() {
    // 开发环境特定配置
}
构建应用
app := builder.Build()  // 构建 WebApplication 实例

WebApplication

运行应用
app := builder.Build()

// 方式 1:使用默认地址运行
app.Run()  // 默认 :8080

// 方式 2:指定地址运行
app.Run("http://localhost:5000")

// 方式 3:使用 Context 运行
ctx := context.Background()
app.RunWithContext(ctx)

// 方式 4:手动控制生命周期
ctx := context.Background()
app.Start(ctx)
// ... 做其他事情
app.Stop(ctx)
访问服务
app := builder.Build()

// 从应用的服务容器解析服务
userService := di.Get[*UserService](app.Services)
config := di.Get[*AppConfig](app.Services)

路由系统

基本路由
app := builder.Build()

// GET 请求
app.MapGet("/hello", func(c *web.HttpContext) web.IActionResult {
    return c.Ok(web.M{"message": "Hello"})
})

// POST 请求
app.MapPost("/users", func(c *web.HttpContext) web.IActionResult {
    var user User
    if err := c.MustBindJSON(&user); err != nil {
        return err
    }
    return c.Created(user)
})

// PUT 请求
app.MapPut("/users/:id", func(c *web.HttpContext) web.IActionResult {
    // 更新逻辑
    return c.Ok(nil)
})

// DELETE 请求
app.MapDelete("/users/:id", func(c *web.HttpContext) web.IActionResult {
    // 删除逻辑
    return c.NoContent()
})

// PATCH 请求
app.MapPatch("/users/:id", func(c *web.HttpContext) web.IActionResult {
    // 部分更新逻辑
    return c.Ok(nil)
})
泛型参数 API(推荐)⭐

CSGO 提供了基于 Go 泛型的现代参数验证 API,具有以下优势:

  • 类型安全:编译时类型检查
  • 更简洁:无需 Params() 前缀和 Check() 调用
  • 自动错误处理:验证错误自动收集并返回
  • 更好的 IDE 支持:完整的类型提示
基本用法
// 路径参数
app.MapGet("/users/:id", func(c *web.HttpContext) web.IActionResult {
    // 直接获取并转换类型
    id := web.Path[int](c, "id").Value()
    return c.Ok(web.M{"id": id})
})

// 查询参数带默认值
app.MapGet("/products", func(c *web.HttpContext) web.IActionResult {
    page := web.Query[int](c, "page").Default(1)
    size := web.Query[int](c, "size").Default(10)
    sort := web.Query[string](c, "sort").Default("date")
    
    return c.Ok(web.M{
        "page": page,
        "size": size,
        "sort": sort,
    })
})

// 请求头参数
app.MapGet("/protected", func(c *web.HttpContext) web.IActionResult {
    token := web.Header[string](c, "Authorization").Required().Value()
    version := web.Header[int](c, "X-API-Version").Default(1)
    
    return c.Ok(web.M{"token": token, "version": version})
})
参数验证

使用 Required()Custom() 方法进行验证:

app.POST("/register", func(c *web.HttpContext) web.IActionResult {
    // 必填参数
    username := web.Query[string](c, "username").
        Required().
        Custom(func(v string) error {
            if len(v) < 3 || len(v) > 20 {
                return errors.New("用户名长度必须在 3-20 个字符之间")
            }
            return nil
        }).
        Value()
    
    // 邮箱验证
    email := web.Query[string](c, "email").
        Required().
        Custom(func(v string) error {
            if !strings.Contains(v, "@") {
                return errors.New("邮箱格式不正确")
            }
            return nil
        }).
        Value()
    
    // 数字范围验证
    age := web.Query[int](c, "age").
        Required().
        Custom(func(v int) error {
            if v < 18 || v > 120 {
                return errors.New("年龄必须在 18-120 之间")
            }
            return nil
        }).
        Value()
    
    // 验证错误会自动返回 400 Bad Request
    // 无需手动检查
    
    return c.Ok(web.M{
        "username": username,
        "email":    email,
        "age":      age,
    })
})
支持的类型
  • string
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • bool
  • time.Time
  • time.Duration
手动错误处理

如果需要自定义错误响应,使用 Get() 方法:

app.MapGet("/search", func(c *web.HttpContext) web.IActionResult {
    keyword, err := web.Query[string](c, "keyword").
        Required().
        Custom(func(v string) error {
            if len(v) < 2 {
                return errors.New("关键词至少需要 2 个字符")
            }
            return nil
        }).
        Get()
    
    if err != nil {
        return c.BadRequest(fmt.Sprintf("搜索失败: %v", err))
    }
    
    return c.Ok(web.M{"keyword": keyword})
})
常用验证模式
// 数字范围
size := web.Query[int](c, "size").Custom(func(v int) error {
    if v < 1 || v > 100 {
        return errors.New("尺寸必须在 1-100 之间")
    }
    return nil
}).Default(10)

// 字符串长度
bio := web.Query[string](c, "bio").Custom(func(v string) error {
    if len(v) > 500 {
        return errors.New("简介不能超过 500 个字符")
    }
    return nil
}).Value()

// 正则表达式
phone := web.Query[string](c, "phone").Custom(func(v string) error {
    matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, v)
    if !matched {
        return errors.New("手机号格式不正确")
    }
    return nil
}).Value()

// 枚举值
status := web.Query[string](c, "status").Custom(func(v string) error {
    validValues := []string{"pending", "active", "inactive"}
    for _, valid := range validValues {
        if v == valid {
            return nil
        }
    }
    return errors.New("状态值无效")
}).Default("pending")

📖 详细迁移指南: 参见 MIGRATION_PARAMS.md

路径参数(传统方式)
// 定义路径参数
app.MapGet("/users/:id", func(c *web.HttpContext) web.IActionResult {
    // 方式 1: 直接获取字符串 (推荐使用泛型 API)
    id := c.RawCtx().Param("id")
    
    // 方式 2: 使用 Deprecated 的参数验证器
    // idInt := c.Params().PathInt("id").Value()  // ⚠️ 已废弃,请使用 web.Path[int]
    
    // 方式 3: 使用新的泛型 API (推荐) ⭐
    idInt, err := web.Path[int](c, "id").Value()
    if err != nil {
        return err
    }
    
    return c.Ok(web.M{"id": idInt})
})

// 多个路径参数
app.MapGet("/users/:userId/orders/:orderId", 
    func(c *web.HttpContext) web.IActionResult {
        userId := c.RawCtx().Param("userId")
        orderId := c.RawCtx().Param("orderId")
        return c.Ok(web.M{"userId": userId, "orderId": orderId})
    })
查询参数
app.MapGet("/search", func(c *web.HttpContext) web.IActionResult {
    // 获取单个查询参数
    keyword := c.RawCtx().Query("keyword")
    
    // 获取带默认值的查询参数
    page := c.RawCtx().DefaultQuery("page", "1")
    
    // 绑定到结构体
    var query SearchQuery
    if ok, err := c.BindQuery(&query); !ok {
        return err
    }
    
    return c.Ok(query)
})

type SearchQuery struct {
    Keyword string `form:"keyword"`
    Page    int    `form:"page"`
    Size    int    `form:"size"`
}
路由组
app := builder.Build()

// 创建 API 路由组
api := app.MapGroup("/api")
{
    // /api/users
    api.MapGet("/users", getUsers)
    api.MapPost("/users", createUser)
    
    // /api/orders
    api.MapGet("/orders", getOrders)
}

// 创建带版本的路由组
v1 := app.MapGroup("/api/v1")
{
    v1.MapGet("/users", getUsersV1)
}

v2 := app.MapGroup("/api/v2")
{
    v2.MapGet("/users", getUsersV2)
}

// 嵌套路由组
api := app.MapGroup("/api")
users := api.MapGroup("/users")
{
    users.MapGet("", listUsers)          // GET /api/users
    users.MapGet("/:id", getUser)        // GET /api/users/:id
    users.MapPost("", createUser)        // POST /api/users
    users.MapPut("/:id", updateUser)     // PUT /api/users/:id
    users.MapDelete("/:id", deleteUser)  // DELETE /api/users/:id
}
路由组中间件
// 为路由组添加中间件
api := app.MapGroup("/api", authMiddleware, loggingMiddleware)
{
    api.MapGet("/users", getUsers)  // 会应用中间件
}

// 或者
api := app.MapGroup("/api")
api.Use(authMiddleware)  // 添加中间件到组
api.MapGet("/users", getUsers)

HttpContext

获取请求信息
func handler(c *web.HttpContext) web.IActionResult {
    // 获取原始 gin.Context
    ginCtx := c.RawCtx()
    
    // 获取请求 Context
    ctx := c.Context()
    
    // 获取请求方法
    method := ginCtx.Request.Method
    
    // 获取请求路径
    path := ginCtx.Request.URL.Path
    
    // 获取请求头
    userAgent := ginCtx.GetHeader("User-Agent")
    
    // 获取 Cookie
    token, err := ginCtx.Cookie("token")
    
    return c.Ok(nil)
}
请求体绑定
type CreateUserRequest struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func createUser(c *web.HttpContext) web.IActionResult {
    var req CreateUserRequest
    
    // 绑定 JSON(返回错误则自动返回 400)
    if err := c.MustBindJSON(&req); err != nil {
        return err
    }
    
    // 或者使用两个返回值的方式
    if ok, err := c.BindJSON(&req); !ok {
        return err
    }
    
    // 使用请求数据
    user := createUserFromRequest(req)
    return c.Created(user)
}
请求验证
type CreateUserRequest struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

// 注册验证器
func init() {
    validator := validation.NewValidator[CreateUserRequest]()
    validator.Field(func(r *CreateUserRequest) string { return r.Name }).
        NotEmpty().
        MinLength(2)
    validator.Field(func(r *CreateUserRequest) string { return r.Email }).
        NotEmpty().
        EmailAddress()
    validation.RegisterValidator[CreateUserRequest](validator)
}

// 使用自动验证
func createUser(c *web.HttpContext) web.IActionResult {
    // 自动绑定并验证
    req, err := web.BindAndValidate[CreateUserRequest](c)
    if err != nil {
        return err  // 自动返回验证错误
    }
    
    // 验证通过,处理业务逻辑
    user := createUserFromRequest(*req)
    return c.Created(user)
}
访问服务
func handler(c *web.HttpContext) web.IActionResult {
    // 从 HttpContext 访问服务容器
    userService := di.Get[*UserService](c.Services)
    
    // 使用服务
    users := userService.GetAllUsers()
    
    return c.Ok(users)
}

ActionResult

成功响应
// 200 OK
return c.Ok(data)
return c.Ok(web.M{"message": "Success"})

// 201 Created
return c.Created(user)

// 204 No Content
return c.NoContent()

响应格式:

{
  "success": true,
  "data": { /* 你的数据 */ }
}
错误响应
// 400 Bad Request
return c.BadRequest("无效的请求参数")

// 401 Unauthorized
return c.Unauthorized("未授权访问")

// 403 Forbidden
return c.Forbidden("没有访问权限")

// 404 Not Found
return c.NotFound("资源不存在")

// 409 Conflict
return c.Conflict("资源冲突")

// 500 Internal Server Error
return c.InternalError("服务器内部错误")

// 自定义错误
return c.Error(418, "I_AM_TEAPOT", "我是一个茶壶")

错误响应格式:

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "资源不存在"
  }
}
验证错误响应
// 验证失败时自动返回
req, err := web.BindAndValidate[CreateUserRequest](c)
if err != nil {
    return err  // 自动格式化验证错误
}

验证错误响应格式:

{
  "success": false,
  "error": {
    "code": "VALIDATION.FAILED",
    "message": "验证失败",
    "fields": [
      {
        "field": "name",
        "message": "不能为空",
        "code": "VALIDATION.REQUIRED"
      },
      {
        "field": "email",
        "message": "邮箱格式不正确",
        "code": "VALIDATION.EMAIL"
      }
    ]
  }
}
业务错误响应

推荐方式:使用 FromError(简洁)

import "github.com/gocrud/csgo/errors"

func getUser(c *web.HttpContext) web.IActionResult {
    user, err := userService.GetUser(id)
    if err != nil {
        // FromError 自动识别错误类型并返回对应的响应
        // BizError -> 自动映射状态码,ValidationErrors -> 400,普通 error -> 500
        return c.FromError(err, "获取用户失败")
    }
    return c.Ok(user)
}

// 服务层
func (s *UserService) GetUser(id int) (*User, error) {
    user, err := s.repo.FindByID(id)
    if err != nil {
        return nil, err
    }
    if user == nil {
        // 使用业务错误构建器
        return nil, errors.Business("USER").NotFound("用户不存在")
    }
    return user, nil
}

传统方式:手动类型判断(仍然支持)

func getUser(c *web.HttpContext) web.IActionResult {
    user, err := userService.GetUser(id)
    if err != nil {
        // 手动判断错误类型
        if bizErr, ok := err.(*errors.BizError); ok {
            return c.BizError(bizErr)
        }
        return c.InternalError("服务器错误")
    }
    return c.Ok(user)
}

自定义错误处理器

// 在应用启动时注册
func init() {
    // 注册数据库错误处理器
    web.RegisterErrorHandler(
        func(err error) bool {
            return errors.Is(err, sql.ErrNoRows)
        },
        func(err error, msg ...string) web.IActionResult {
            return web.Error(404, "NOT_FOUND", "记录不存在")
        },
    )
}

// 控制器中使用
func getUser(c *web.HttpContext) web.IActionResult {
    user, err := repo.FindByID(id)  // 可能返回 sql.ErrNoRows
    if err != nil {
        return c.FromError(err, "用户不存在")  // 自动应用处理器
    }
    return c.Ok(user)
}
其他响应类型
// 重定向
return web.Redirect("/new-url")
return web.RedirectPermanent("/new-url")

// 纯文本
return web.Content(200, "Plain text response")

// 自定义 JSON(不使用标准格式)
return web.Json(200, web.M{"custom": "format"})

// 文件下载
return web.File("/path/to/file.pdf")
return web.FileDownload("/path/to/file.pdf", "download.pdf")

// 图片响应(二进制流)
return web.PNG(imageData)
return web.JPEG(imageData)
return web.WebP(imageData)
return web.BinaryImage(imageData, "image/gif")

// 图片响应(Base64编码的JSON)
return web.Base64Image(imageData, "image/png")

// 仅状态码
return web.Status(204)
图片响应详解

框架提供了专门的图片响应方法:

// 方式1:二进制图片流(直接返回图片数据)
func getAvatar(c *web.HttpContext) web.IActionResult {
    imageData, _ := loadImageFromDB()
    return web.PNG(imageData)  // 返回PNG格式
}

// 方式2:Base64编码(包含在JSON中)
func getThumbnail(c *web.HttpContext) web.IActionResult {
    imageData, _ := loadThumbnailFromDB()
    return web.Base64Image(imageData, "image/png")
}
// 响应格式:{"success": true, "data": {"image": "base64...", "contentType": "image/png"}}

// 所有支持的图片格式
web.PNG(imageData)           // image/png
web.JPEG(imageData)          // image/jpeg
web.WebP(imageData)          // image/webp
web.BinaryImage(data, type)  // 自定义类型

控制器模式

定义控制器
type UserController struct {
    userService *UserService
    logger      logging.ILogger
}

func NewUserController(
    userService *UserService,
    loggerFactory logging.ILoggerFactory,
) *UserController {
    return &UserController{
        userService: userService,
        logger:      logging.GetLogger[UserController](loggerFactory),
    }
}

// 实现 IController 接口
func (ctrl *UserController) MapRoutes(app *web.WebApplication) {
    users := app.MapGroup("/api/users")
    users.MapGet("", ctrl.List)
    users.MapGet("/:id", ctrl.Get)
    users.MapPost("", ctrl.Create)
    users.MapPut("/:id", ctrl.Update)
    users.MapDelete("/:id", ctrl.Delete)
}

// 控制器方法
func (ctrl *UserController) List(c *web.HttpContext) web.IActionResult {
    users := ctrl.userService.GetAll()
    return c.Ok(users)
}

func (ctrl *UserController) Get(c *web.HttpContext) web.IActionResult {
    id := c.Params().PathInt("id").Value()
    user, err := ctrl.userService.GetByID(id)
    if err != nil {
        if bizErr, ok := err.(*errors.BizError); ok {
            return c.BizError(bizErr)
        }
        return c.InternalError("服务器错误")
    }
    return c.Ok(user)
}

func (ctrl *UserController) Create(c *web.HttpContext) web.IActionResult {
    req, err := web.BindAndValidate[CreateUserRequest](c)
    if err != nil {
        return err
    }
    
    user, err := ctrl.userService.Create(req)
    if err != nil {
        return c.handleError(err)
    }
    
    return c.Created(user)
}

// 统一错误处理
func (ctrl *UserController) handleError(err error) web.IActionResult {
    if bizErr, ok := err.(*errors.BizError); ok {
        return web.BizError(bizErr)
    }
    ctrl.logger.LogError(err, "Unexpected error")
    return web.InternalError("服务器错误")
}
注册控制器
func main() {
    builder := web.CreateBuilder()
    
    // 注册服务
    builder.Services.Add(NewUserService)
    
    // 注册控制器
    web.AddController(builder.Services, NewUserController)
    
    app := builder.Build()
    
    // 自动映射所有控制器路由
    app.MapControllers()
    
    app.Run()
}

中间件

使用中间件
app := builder.Build()

// 全局中间件
app.Use(loggingMiddleware)
app.Use(authMiddleware)

// 定义路由
app.MapGet("/api/users", getUsers)
自定义中间件
// 日志中间件
func loggingMiddleware(c *gin.Context) {
    start := time.Now()
    
    // 处理请求
    c.Next()
    
    // 请求完成后
    latency := time.Since(start)
    status := c.Writer.Status()
    
    fmt.Printf("[%s] %s %d %v\n", 
        c.Request.Method,
        c.Request.URL.Path,
        status,
        latency,
    )
}

// 认证中间件
func authMiddleware(c *gin.Context) {
    token := c.GetHeader("Authorization")
    
    if token == "" {
        c.JSON(401, web.M{"error": "Unauthorized"})
        c.Abort()  // 停止后续处理
        return
    }
    
    // 验证 token
    user, err := validateToken(token)
    if err != nil {
        c.JSON(401, web.M{"error": "Invalid token"})
        c.Abort()
        return
    }
    
    // 设置用户信息到上下文
    c.Set("user", user)
    c.Next()
}

// 使用
app.Use(loggingMiddleware)
app.Use(authMiddleware)
路由级中间件
// 只应用到特定路由
app.MapGet("/admin/users", authMiddleware, getAdminUsers)

// 应用到路由组
admin := app.MapGroup("/admin", authMiddleware)
{
    admin.MapGet("/users", getAdminUsers)
    admin.MapPost("/users", createAdminUser)
}
恢复中间件

Gin 默认包含恢复中间件,捕获 panic 并返回 500:

// 已自动启用,无需手动添加
// 如果 panic,会自动返回 500 错误

CORS 配置

启用 CORS
builder := web.CreateBuilder()

// 添加 CORS 支持
builder.AddCors(func(opts *web.CorsOptions) {
    opts.AllowOrigins = []string{"http://localhost:3000"}
    opts.AllowMethods = []string{"GET", "POST", "PUT", "DELETE"}
    opts.AllowHeaders = []string{"Origin", "Content-Type", "Authorization"}
    opts.AllowCredentials = true
    opts.MaxAge = 12 * time.Hour
})

app := builder.Build()

// 使用 CORS 中间件
app.UseCors()

app.MapGet("/api/users", getUsers)
app.Run()
开发环境 CORS
builder := web.CreateBuilder()

if builder.Environment.IsDevelopment() {
    // 开发环境允许所有源
    builder.AddCors(func(opts *web.CorsOptions) {
        opts.AllowAllOrigins = true
        opts.AllowMethods = []string{"*"}
        opts.AllowHeaders = []string{"*"}
    })
}

app := builder.Build()
app.UseCors()

静态文件

提供静态文件
app := builder.Build()

// 提供静态文件目录
app.ServeStaticFiles("/static", "./public")
// 访问:http://localhost:8080/static/image.jpg -> ./public/image.jpg

// 提供单个文件
app.ServeStaticFile("/favicon.ico", "./assets/favicon.ico")

// SPA 应用支持
app.ServeStaticFiles("/", "./dist")
app.ServeSPA("./dist/index.html")  // 所有未匹配路由返回 index.html

最佳实践

1. 使用 HttpContext 和 ActionResult
// ✅ 推荐:使用 HttpContext 和 ActionResult
func handler(c *web.HttpContext) web.IActionResult {
    return c.Ok(data)
}

// ❌ 不推荐:直接使用 gin.Context
func handler(c *gin.Context) {
    c.JSON(200, web.M{"data": data})
}
2. 统一响应格式
// ✅ 使用 ActionResult,自动格式化响应
return c.Ok(user)
return c.BadRequest("Invalid input")
return c.NotFound("User not found")

// ❌ 手动构建响应
c.RawCtx().JSON(200, web.M{"success": true, "data": user})
3. 使用控制器组织代码
// ✅ 推荐:使用控制器
type UserController struct {
    service *UserService
}

func (ctrl *UserController) MapRoutes(app *web.WebApplication) {
    users := app.MapGroup("/api/users")
    users.MapGet("", ctrl.List)
    users.MapPost("", ctrl.Create)
}

// ❌ 不推荐:所有路由在 main 中定义
func main() {
    app.MapGet("/api/users", func(...) {...})
    app.MapPost("/api/users", func(...) {...})
    // 大量路由定义...
}
4. 验证器复用
// ✅ 定义并注册验证器
func init() {
    validation.RegisterValidator[CreateUserRequest](NewCreateUserValidator())
}

// 在多个地方使用
func createUser(c *web.HttpContext) web.IActionResult {
    req, err := web.BindAndValidate[CreateUserRequest](c)
    if err != nil {
        return err
    }
    // ...
}
5. 错误处理分层
// ✅ 推荐:服务层抛出业务错误,控制器使用 FromError
// 服务层:抛出业务错误
func (s *UserService) GetUser(id int) (*User, error) {
    if user == nil {
        return nil, errors.Business("USER").NotFound("用户不存在")
    }
    return user, nil
}

// 控制器层:使用 FromError 自动处理
func (ctrl *UserController) GetUser(c *web.HttpContext) web.IActionResult {
    user, err := ctrl.service.GetUser(id)
    if err != nil {
        return c.FromError(err, "获取用户失败")  // 一行搞定!
    }
    return c.Ok(user)
}

// ❌ 不推荐:手动类型判断(样板代码多)
func (ctrl *UserController) GetUser(c *web.HttpContext) web.IActionResult {
    user, err := ctrl.service.GetUser(id)
    if err != nil {
        if bizErr, ok := err.(*errors.BizError); ok {
            return c.BizError(bizErr)
        }
        return c.InternalError("服务器错误")
    }
    return c.Ok(user)
}
6. 使用路由组组织 API
// ✅ 推荐:使用路由组
api := app.MapGroup("/api")
v1 := api.MapGroup("/v1")
{
    users := v1.MapGroup("/users")
    users.MapGet("", listUsers)
    users.MapPost("", createUser)
    
    orders := v1.MapGroup("/orders")
    orders.MapGet("", listOrders)
}

// ❌ 不推荐:扁平化路由
app.MapGet("/api/v1/users", listUsers)
app.MapPost("/api/v1/users", createUser)
app.MapGet("/api/v1/orders", listOrders)
7. 中间件顺序
app := builder.Build()

// 正确的中间件顺序
app.Use(recoveryMiddleware)      // 1. 异常恢复
app.Use(loggingMiddleware)        // 2. 日志记录
app.Use(corsMiddleware)           // 3. CORS
app.Use(authMiddleware)           // 4. 认证
app.Use(rateLimitMiddleware)      // 5. 限流

// 定义路由
app.MapGet("/api/users", getUsers)

API 参考

WebApplicationBuilder
// 创建构建器
CreateBuilder(args ...string) *WebApplicationBuilder

// 访问属性
builder.Services      // IServiceCollection
builder.Configuration // IConfigurationManager
builder.Environment   // IHostEnvironment
builder.WebHost       // WebHost 配置

// 构建应用
builder.Build() *WebApplication
WebApplication
// 运行应用
Run(urls ...string) error
RunWithContext(ctx context.Context) error
Start(ctx context.Context) error
Stop(ctx context.Context) error

// 路由
MapGet(pattern string, handlers ...Handler) IEndpointConventionBuilder
MapPost(pattern string, handlers ...Handler) IEndpointConventionBuilder
MapPut(pattern string, handlers ...Handler) IEndpointConventionBuilder
MapDelete(pattern string, handlers ...Handler) IEndpointConventionBuilder
MapPatch(pattern string, handlers ...Handler) IEndpointConventionBuilder
MapGroup(prefix string, handlers ...Handler) *RouteGroupBuilder

// 控制器
MapControllers()

// 中间件
Use(middleware ...gin.HandlerFunc)

// 静态文件
ServeStaticFiles(prefix, root string)
ServeStaticFile(path, filepath string)
HttpContext
// 访问原始上下文
RawCtx() *gin.Context
Context() context.Context

// 服务容器
Services di.IServiceProvider

// 成功响应
Ok(data interface{}) IActionResult
Created(data interface{}) IActionResult
NoContent() IActionResult

// 错误响应
BadRequest(message string) IActionResult
Unauthorized(message string) IActionResult
Forbidden(message string) IActionResult
NotFound(message string) IActionResult
InternalError(message string) IActionResult

// 绑定
BindJSON(target interface{}) (bool, IActionResult)
MustBindJSON(target interface{}) IActionResult
BindQuery(target interface{}) (bool, IActionResult)

// 验证
BindAndValidate[T any](c *HttpContext) (*T, IActionResult)

// 图片响应
PNG(imageData []byte) IActionResult
JPEG(imageData []byte) IActionResult
WebP(imageData []byte) IActionResult
BinaryImage(imageData []byte, contentType string) IActionResult
Base64Image(imageData []byte, contentType string) IActionResult

常见问题

如何获取请求头?
func handler(c *web.HttpContext) web.IActionResult {
    token := c.RawCtx().GetHeader("Authorization")
    userAgent := c.RawCtx().GetHeader("User-Agent")
    return c.Ok(nil)
}
如何设置响应头?
func handler(c *web.HttpContext) web.IActionResult {
    c.RawCtx().Header("X-Custom-Header", "value")
    return c.Ok(data)
}
如何处理文件上传?
func uploadFile(c *web.HttpContext) web.IActionResult {
    file, err := c.RawCtx().FormFile("file")
    if err != nil {
        return c.BadRequest("No file uploaded")
    }
    
    // 保存文件
    dst := fmt.Sprintf("./uploads/%s", file.Filename)
    if err := c.RawCtx().SaveUploadedFile(file, dst); err != nil {
        return c.InternalError("Failed to save file")
    }
    
    return c.Ok(web.M{"filename": file.Filename})
}
如何在中间件中传递数据?
// 在中间件中设置
func authMiddleware(c *gin.Context) {
    user := getUserFromToken(c)
    c.Set("user", user)
    c.Next()
}

// 在处理器中获取
func handler(c *web.HttpContext) web.IActionResult {
    user, exists := c.RawCtx().Get("user")
    if !exists {
        return c.Unauthorized("Not authenticated")
    }
    return c.Ok(user)
}
HttpContext 和 gin.Context 的关系?

HttpContext 包装了 gin.Context,提供了统一的 API。你可以通过 c.RawCtx() 访问原始的 gin.Context:

func handler(c *web.HttpContext) web.IActionResult {
    ginCtx := c.RawCtx()  // 获取原始 gin.Context
    // 使用 gin.Context 的所有方法
    ginCtx.JSON(200, data)
    return nil
}

← 返回主目录

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddController

func AddController(services di.IServiceCollection, constructor any)

AddController 注册控制器工厂以供自动发现。 控制器将在调用 MapControllers() 时作为单例创建。

重要:控制器是单例,必须是无状态的。不要在控制器字段中存储 特定于请求的数据。

用法:

// 使用构造函数
web.AddController(builder.Services, NewUserController)

func AddControllerInstance

func AddControllerInstance(services di.IServiceCollection, factory func(di.IServiceProvider) IController)

AddControllerInstance 注册现有的控制器实例。 当您需要更多地控制控制器创建时使用此方法。

用法:

web.AddControllerInstance(builder.Services, func(sp di.IServiceProvider) web.IController {
    return NewUserController(sp)
})

func ClearErrorHandlers

func ClearErrorHandlers()

ClearErrorHandlers 清除所有自定义错误处理器。 主要用于测试场景。

func GetRegisteredControllerCount

func GetRegisteredControllerCount() int

GetRegisteredControllerCount 返回已注册控制器的数量。 这主要用于测试和调试。

func MakeToGinHandler

func MakeToGinHandler(services di.IServiceProvider) func(Handler) gin.HandlerFunc

MakeToGinHandler 创建一个处理器转换器,将服务注入到 HttpContext 中。 此工厂函数捕获服务并返回转换器函数。 支持 ActionHandlerFunc 和 gin.HandlerFunc 两种类型:

  • ActionHandlerFunc: func(*HttpContext) IActionResult
  • gin.HandlerFunc: func(*gin.Context)

func MakeToGinHandlers

func MakeToGinHandlers(services di.IServiceProvider) func(...Handler) []gin.HandlerFunc

MakeToGinHandlers 创建一个函数,用于转换多个处理器并注入服务。 支持混合使用 ActionHandlerFunc 和 gin.HandlerFunc。

func RegisterErrorHandler

func RegisterErrorHandler[T error](handler func(T, ...string) IActionResult)

RegisterErrorHandler 注册错误类型处理器(泛型版本)。 T: 错误类型,handler: 处理函数。

使用示例:

// 注册自定义错误处理器
web.RegisterErrorHandler[*MyCustomError](func(err *MyCustomError, msg ...string) web.IActionResult {
    return web.BadRequest(err.Details)
})

// 注册数据库错误处理器
web.RegisterErrorHandler[*sql.ErrNoRows](func(err *sql.ErrNoRows, msg ...string) web.IActionResult {
    return web.NotFound("记录不存在")
})

func ResetControllers

func ResetControllers()

ResetControllers 清除所有已注册的控制器工厂。 这主要用于测试。

Types

type ActionHandlerFunc

type ActionHandlerFunc func(*HttpContext) IActionResult

ActionHandlerFunc 是返回 IActionResult 的处理器函数。

type ApiError

type ApiError struct {
	Code    string                       `json:"code"`              // 错误码
	Message string                       `json:"message"`           // 错误消息
	Fields  []validation.ValidationError `json:"fields,omitempty"`  // 验证错误字段列表
	Details M                            `json:"details,omitempty"` // 额外详情(可选)
}

ApiError 表示 API 响应中的错误。

type ApiResponse

type ApiResponse struct {
	Success bool        `json:"success"`
	Data    interface{} `json:"data,omitempty"`
	Error   *ApiError   `json:"error,omitempty"`
}

ApiResponse 是标准的 API 响应格式。

type Base64ImageResult

type Base64ImageResult struct {
	StatusCode  int
	ImageData   string // Base64 编码的图片
	ContentType string // 原始图片内容类型(如 image/png)
}

Base64ImageResult 表示以 base64 格式在 JSON 中返回的图片响应。

func (Base64ImageResult) ExecuteResult

func (r Base64ImageResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type BinaryImageResult

type BinaryImageResult struct {
	StatusCode  int
	ImageData   []byte
	ContentType string // 如 image/png、image/jpeg
}

BinaryImageResult 表示二进制图片响应。

func (BinaryImageResult) ExecuteResult

func (r BinaryImageResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type BoolParamRule

type BoolParamRule struct {
	// contains filtered or unexported fields
}

BoolParamRule 布尔参数规则

func (*BoolParamRule) Optional

func (r *BoolParamRule) Optional() *BoolParamRule

Optional 可选参数

func (*BoolParamRule) Required

func (r *BoolParamRule) Required() *BoolParamRule

Required 必填验证

func (*BoolParamRule) Value

func (r *BoolParamRule) Value() bool

Value 获取验证后的值

func (*BoolParamRule) ValueOr

func (r *BoolParamRule) ValueOr(defaultValue bool) bool

ValueOr 获取值,如果解析失败则返回默认值

type ConfigureHostBuilder

type ConfigureHostBuilder struct {
	// contains filtered or unexported fields
}

ConfigureHostBuilder allows configuring the generic host.

func (*ConfigureHostBuilder) ConfigureServices

func (c *ConfigureHostBuilder) ConfigureServices(configure func(di.IServiceCollection)) *ConfigureHostBuilder

ConfigureServices configures services for the host.

type ConfigureWebHostBuilder

type ConfigureWebHostBuilder struct {
	// contains filtered or unexported fields
}

ConfigureWebHostBuilder allows configuring the web host.

func (*ConfigureWebHostBuilder) UseShutdownTimeout

func (c *ConfigureWebHostBuilder) UseShutdownTimeout(seconds int) *ConfigureWebHostBuilder

UseShutdownTimeout configures the shutdown timeout. Corresponds to .NET builder.WebHost.UseShutdownTimeout().

func (*ConfigureWebHostBuilder) UseUrls

UseUrls configures the URLs the web server listens on.

type ContentResult

type ContentResult struct {
	StatusCode  int
	Content     string
	ContentType string
}

ContentResult 表示纯文本响应。

func (ContentResult) ExecuteResult

func (r ContentResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type ControllerBase

type ControllerBase struct {
	Services di.IServiceProvider
}

ControllerBase 为控制器提供通用功能。 在您的控制器中嵌入此结构以访问通用服务。

func NewControllerBase

func NewControllerBase(services di.IServiceProvider) ControllerBase

NewControllerBase 创建一个新的 ControllerBase,使用给定的服务提供者。

type ControllerOptions

type ControllerOptions struct {
	// EnableEndpointMetadata 启用 OpenAPI 生成的端点元数据
	EnableEndpointMetadata bool
}

ControllerOptions 表示控制器配置选项。

type CorsOptions

type CorsOptions struct {
	AllowOrigins     []string
	AllowMethods     []string
	AllowHeaders     []string
	ExposeHeaders    []string
	AllowCredentials bool
	MaxAge           time.Duration
}

CorsOptions 表示 CORS 配置选项。 对应 .NET 的 CorsOptions。

func NewCorsOptions

func NewCorsOptions() *CorsOptions

NewCorsOptions 创建默认的 CORS 选项。

type CreatedResult

type CreatedResult struct {
	Data interface{}
}

CreatedResult 表示 201 Created 响应。

func (CreatedResult) ExecuteResult

func (r CreatedResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type ErrorHandler

type ErrorHandler func(err error, defaultMessage ...string) IActionResult

ErrorHandler 错误处理器函数类型。 接收错误和默认消息,返回 IActionResult。 如果返回 nil,表示该处理器不处理此错误,继续尝试其他处理器。

type ErrorResult

type ErrorResult struct {
	StatusCode int
	Code       string
	Message    string
}

ErrorResult 表示错误响应。

func (ErrorResult) ExecuteResult

func (r ErrorResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type FileResult

type FileResult struct {
	FilePath string
	FileName string
}

FileResult 表示文件下载响应。

func (FileResult) ExecuteResult

func (r FileResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type FloatParamRule

type FloatParamRule struct {
	// contains filtered or unexported fields
}

FloatParamRule 浮点数参数规则

func (*FloatParamRule) Max

func (r *FloatParamRule) Max(max float64) *FloatParamRule

Max 最大值验证

func (*FloatParamRule) Min

func (r *FloatParamRule) Min(min float64) *FloatParamRule

Min 最小值验证

func (*FloatParamRule) Optional

func (r *FloatParamRule) Optional() *FloatParamRule

Optional 可选参数

func (*FloatParamRule) Positive

func (r *FloatParamRule) Positive() *FloatParamRule

Positive 正数验证

func (*FloatParamRule) Range

func (r *FloatParamRule) Range(min, max float64) *FloatParamRule

Range 范围验证

func (*FloatParamRule) Required

func (r *FloatParamRule) Required() *FloatParamRule

Required 必填验证

func (*FloatParamRule) Value

func (r *FloatParamRule) Value() float64

Value 获取验证后的值

func (*FloatParamRule) ValueOr

func (r *FloatParamRule) ValueOr(defaultValue float64) float64

ValueOr 获取值,如果解析失败则返回默认值

type FrameworkErrorResult

type FrameworkErrorResult struct {
	StatusCode int
	Error      *errors.Error
}

FrameworkErrorResult 表示框架错误响应。

func (FrameworkErrorResult) ExecuteResult

func (r FrameworkErrorResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type Handler

type Handler interface{}

Handler 表示统一的处理器类型,可以是 ActionHandlerFunc 或 gin.HandlerFunc。 支持两种类型:

  • ActionHandlerFunc: func(*HttpContext) IActionResult
  • gin.HandlerFunc: func(*gin.Context)

type HttpContext

type HttpContext struct {

	// Services 提供对应用程序 DI 容器的访问。
	// 使用 di.Get[T](ctx.Services) 来解析服务。
	Services di.IServiceProvider
	// contains filtered or unexported fields
}

func NewHttpContext

func NewHttpContext(c *gin.Context) *HttpContext

NewHttpContext 从 gin.Context 创建新的 HttpContext。

func (*HttpContext) BadRequest

func (c *HttpContext) BadRequest(message string) IActionResult

BadRequest 返回 400 Bad Request。

func (*HttpContext) BadRequestWithCode

func (c *HttpContext) BadRequestWithCode(code, message string) IActionResult

BadRequestWithCode 返回 400 Bad Request,带有自定义错误码。

func (*HttpContext) BindJSON

func (c *HttpContext) BindJSON(target interface{}) (ok bool, result IActionResult)

BindJSON 将 JSON 请求体绑定到目标对象,失败时返回 BadRequest。 绑定成功时返回 true,否则返回 false。

func (*HttpContext) BindQuery

func (c *HttpContext) BindQuery(target interface{}) (ok bool, result IActionResult)

BindQuery 将查询参数绑定到目标对象,失败时返回 BadRequest。

func (*HttpContext) Conflict

func (c *HttpContext) Conflict(message string) IActionResult

Conflict 返回 409 Conflict。

func (*HttpContext) Context

func (c *HttpContext) Context() context.Context

Context 返回请求的上下文。

func (*HttpContext) Created

func (c *HttpContext) Created(data interface{}) IActionResult

Created 返回 201 Created 及数据。

func (*HttpContext) Error

func (c *HttpContext) Error(statusCode int, code, message string) IActionResult

Error 返回自定义错误响应。

func (*HttpContext) Forbidden

func (c *HttpContext) Forbidden(message string) IActionResult

Forbidden 返回 403 Forbidden。

func (*HttpContext) FrameworkError

func (c *HttpContext) FrameworkError(err *errors.Error) IActionResult

FrameworkError 返回框架错误,自动映射 HTTP 状态码。

func (*HttpContext) FrameworkErrorWithStatus

func (c *HttpContext) FrameworkErrorWithStatus(statusCode int, err *errors.Error) IActionResult

FrameworkErrorWithStatus 返回框架错误,带有指定的 HTTP 状态码。

func (*HttpContext) FromError

func (c *HttpContext) FromError(err error, defaultMessage ...string) IActionResult

FromError 智能处理错误,是 web.FromError 的便捷方法。 自动识别错误类型并返回对应的 ActionResult。

使用示例:

user, err := service.GetUser(id)
if err != nil {
    return c.FromError(err, "获取用户失败")
}

func (*HttpContext) FromErrorWithStatus

func (c *HttpContext) FromErrorWithStatus(err error, statusCode int, defaultMessage ...string) IActionResult

FromErrorWithStatus 智能处理错误并指定状态码。 对于普通 error 使用指定的状态码,对于 BizError 和 ValidationErrors 忽略状态码。

使用示例:

err := db.Connect()
if err != nil {
    return c.FromErrorWithStatus(err, 503, "数据库服务暂时不可用")
}

func (*HttpContext) GetParamErrors

func (c *HttpContext) GetParamErrors() validation.ValidationErrors

GetParamErrors 获取所有参数验证错误。

func (*HttpContext) HasParamErrors

func (c *HttpContext) HasParamErrors() bool

HasParamErrors 检查是否有参数验证错误。

func (*HttpContext) InternalError

func (c *HttpContext) InternalError(message string) IActionResult

InternalError 返回 500 Internal Server Error。

func (*HttpContext) MustBindJSON

func (c *HttpContext) MustBindJSON(target interface{}) IActionResult

MustBindJSON 将 JSON 请求体绑定到目标对象,失败时返回 BadRequest。 这是一个便捷方法,仅返回错误结果。

func (*HttpContext) NoContent

func (c *HttpContext) NoContent() IActionResult

NoContent 返回 204 No Content。

func (*HttpContext) NotFound

func (c *HttpContext) NotFound(message string) IActionResult

NotFound 返回 404 Not Found。

func (*HttpContext) Ok

func (c *HttpContext) Ok(data interface{}) IActionResult

Ok 返回 200 OK 及数据。

func (*HttpContext) Params deprecated

func (c *HttpContext) Params() *ParamValidator

Params 创建参数验证器

Deprecated: 使用新的泛型参数 API 代替:web.Path[T], web.Query[T], web.Header[T]

迁移示例:

// 旧 API:
id := c.Params().PathInt("id").Min(1).Value()

// 新 API:
id := web.Path[int](c, "id").Min(1).Value()

新 API 的优势:

  • 更简洁:无需 Params() 前缀和 Check() 调用
  • 类型安全:使用 Go 泛型,编译时检查类型
  • 自动错误处理:验证错误自动收集并返回
  • 更好的 IDE 支持:完整的类型提示和自动补全

func (*HttpContext) RawCtx

func (c *HttpContext) RawCtx() *gin.Context

RawCtx 返回底层的 gin.Context。

func (*HttpContext) Unauthorized

func (c *HttpContext) Unauthorized(message string) IActionResult

Unauthorized 返回 401 Unauthorized。

func (*HttpContext) ValidationBadRequest

func (c *HttpContext) ValidationBadRequest(errs validation.ValidationErrors) IActionResult

ValidationBadRequest 返回 400 Bad Request,带有验证错误。

func (*HttpContext) ValidationBadRequestWithCode

func (c *HttpContext) ValidationBadRequestWithCode(code string, errs validation.ValidationErrors) IActionResult

ValidationBadRequestWithCode 返回 400 Bad Request,带有验证错误和自定义错误码。

type HttpServer

type HttpServer struct {
	*hosting.BackgroundService
	// contains filtered or unexported fields
}

HttpServer is a hosted service that runs the HTTP server.

func NewHttpServer

func NewHttpServer(addr string, engine *gin.Engine, getUrls func() []string) *HttpServer

NewHttpServer creates a new HTTP server.

type IActionResult

type IActionResult interface {
	// ExecuteResult 将结果写入响应。
	ExecuteResult(c *gin.Context)
}

IActionResult 表示操作方法的结果。 类似于 .NET 的 IActionResult 接口。

func BadRequest

func BadRequest(message string) IActionResult

BadRequest 创建 400 Bad Request 结果。

func BadRequestWithCode

func BadRequestWithCode(code, message string) IActionResult

BadRequestWithCode 创建 400 Bad Request 结果,带有自定义错误码。

func Base64Image

func Base64Image(imageData []byte, contentType string) IActionResult

Base64Image 创建 base64 图片结果。 图片数据将被编码为 base64 并以 JSON 格式返回。

func BinaryImage

func BinaryImage(imageData []byte, contentType string) IActionResult

BinaryImage 创建二进制图片结果。 图片数据将以指定的内容类型作为原始二进制返回。

func Conflict

func Conflict(message string) IActionResult

Conflict 创建 409 Conflict 结果。

func Content

func Content(statusCode int, content string) IActionResult

Content 创建纯文本结果。

func ContentWithType

func ContentWithType(statusCode int, content, contentType string) IActionResult

ContentWithType 创建内容结果,带有自定义内容类型。

func Created

func Created(data interface{}) IActionResult

Created 创建 201 Created 结果及数据。

func Error

func Error(statusCode int, code, message string) IActionResult

Error 创建自定义错误结果。

func File

func File(filePath string) IActionResult

File 创建文件结果。

func FileDownload

func FileDownload(filePath, fileName string) IActionResult

FileDownload 创建文件下载结果,带有自定义文件名。

func Forbidden

func Forbidden(message string) IActionResult

Forbidden 创建 403 Forbidden 结果。

func FrameworkError

func FrameworkError(err *errors.Error) IActionResult

FrameworkError 创建框架错误结果,自动映射 HTTP 状态码。 将常见错误模式映射到适当的 HTTP 状态码: - NOT_FOUND -> 404 - ALREADY_EXISTS -> 409 - PERMISSION_DENIED -> 403 - INVALID_* -> 400 - 默认 -> 400

func FrameworkErrorWithStatus

func FrameworkErrorWithStatus(statusCode int, err *errors.Error) IActionResult

FrameworkErrorWithStatus 创建框架错误结果,带有指定的 HTTP 状态码。

func FromError

func FromError(err error, defaultMessage ...string) IActionResult

FromError 智能处理各种类型的错误并返回对应的 ActionResult。 错误处理优先级: 1. 自定义错误处理器(如果已注册) 2. *errors.Error:自动映射 HTTP 状态码 3. validation.ValidationErrors:返回验证错误响应 4. 普通 error:返回内部错误,使用自定义消息

使用示例:

user, err := service.GetUser(id)
if err != nil {
    return web.FromError(err, "获取用户失败")
}

func FromErrorWithStatus

func FromErrorWithStatus(err error, statusCode int, defaultMessage ...string) IActionResult

FromErrorWithStatus 类似 FromError,但允许为普通 error 指定自定义 HTTP 状态码。 错误处理优先级: 1. 自定义错误处理器(如果已注册) 2. *errors.Error:忽略 statusCode,使用自动映射 3. validation.ValidationErrors:忽略 statusCode,固定返回 400 4. 普通 error:使用指定的 statusCode

使用示例:

err := db.Connect()
if err != nil {
    return web.FromErrorWithStatus(err, 503, "数据库服务暂时不可用")
}

func InternalError

func InternalError(message string) IActionResult

InternalError 创建 500 Internal Server Error 结果。

func JPEG

func JPEG(imageData []byte) IActionResult

JPEG 创建 JPEG 图片结果。 BinaryImage 的便捷方法,内容类型为 image/jpeg。

func JSON

func JSON(statusCode int, data interface{}) IActionResult

JSON 创建自定义 JSON 结果。

func NoContent

func NoContent() IActionResult

NoContent 创建 204 No Content 结果。

func NotFound

func NotFound(message string) IActionResult

NotFound 创建 404 Not Found 结果。

func Ok

func Ok(data interface{}) IActionResult

Ok 创建 200 OK 结果及数据。

func PNG

func PNG(imageData []byte) IActionResult

PNG 创建 PNG 图片结果。 BinaryImage 的便捷方法,内容类型为 image/png。

func Redirect

func Redirect(location string) IActionResult

Redirect 创建 302 Found 重定向结果。

func RedirectPermanent

func RedirectPermanent(location string) IActionResult

RedirectPermanent 创建 301 Moved Permanently 重定向结果。

func ShouldBindHeader

func ShouldBindHeader[T any](c *HttpContext) (*T, IActionResult)

ShouldBindHeader 绑定 Header 并验证

func ShouldBindJSON

func ShouldBindJSON[T any](c *HttpContext) (*T, IActionResult)

ShouldBindJSON 绑定 JSON 并验证 自动使用注册验证器的模式(快速失败或全量验证)

func ShouldBindPlain

func ShouldBindPlain[T any](c *HttpContext) (*T, IActionResult)

ShouldBindPlain 绑定 Plain 文本并验证

func ShouldBindQuery

func ShouldBindQuery[T any](c *HttpContext) (*T, IActionResult)

ShouldBindQuery 绑定 Query 参数并验证

func ShouldBindTOML

func ShouldBindTOML[T any](c *HttpContext) (*T, IActionResult)

ShouldBindTOML 绑定 TOML 并验证

func ShouldBindUri

func ShouldBindUri[T any](c *HttpContext) (*T, IActionResult)

ShouldBindUri 绑定 URI 参数并验证

func ShouldBindXML

func ShouldBindXML[T any](c *HttpContext) (*T, IActionResult)

ShouldBindXML 绑定 XML 并验证

func ShouldBindYAML

func ShouldBindYAML[T any](c *HttpContext) (*T, IActionResult)

ShouldBindYAML 绑定 YAML 并验证

func Status

func Status(statusCode int) IActionResult

Status 创建仅包含状态码的结果。

func Unauthorized

func Unauthorized(message string) IActionResult

Unauthorized 创建 401 Unauthorized 结果。

func ValidationBadRequest

func ValidationBadRequest(errs validation.ValidationErrors) IActionResult

ValidationBadRequest 创建 400 Bad Request 结果,带有验证错误。

func ValidationBadRequestWithCode

func ValidationBadRequestWithCode(code string, errs validation.ValidationErrors) IActionResult

ValidationBadRequestWithCode 创建 400 Bad Request 结果,带有验证错误和自定义错误码。

func WebP

func WebP(imageData []byte) IActionResult

WebP 创建 WebP 图片结果。 BinaryImage 的便捷方法,内容类型为 image/webp。

type IController

type IController interface {
	// MapRoutes 向应用程序注册控制器的路由。
	MapRoutes(app *WebApplication)
}

IController 定义控制器接口。 实现此接口的控制器可以被 MapControllers() 自动发现和注册。

type Int64ParamRule

type Int64ParamRule struct {
	// contains filtered or unexported fields
}

Int64ParamRule int64 参数规则

func (*Int64ParamRule) Max

func (r *Int64ParamRule) Max(max int64) *Int64ParamRule

Max 最大值验证

func (*Int64ParamRule) Min

func (r *Int64ParamRule) Min(min int64) *Int64ParamRule

Min 最小值验证

func (*Int64ParamRule) NonNegative

func (r *Int64ParamRule) NonNegative() *Int64ParamRule

NonNegative 非负数验证

func (*Int64ParamRule) Optional

func (r *Int64ParamRule) Optional() *Int64ParamRule

Optional 可选参数

func (*Int64ParamRule) Positive

func (r *Int64ParamRule) Positive() *Int64ParamRule

Positive 正数验证

func (*Int64ParamRule) Range

func (r *Int64ParamRule) Range(min, max int64) *Int64ParamRule

Range 范围验证

func (*Int64ParamRule) Required

func (r *Int64ParamRule) Required() *Int64ParamRule

Required 必填验证

func (*Int64ParamRule) Value

func (r *Int64ParamRule) Value() int64

Value 获取验证后的值

func (*Int64ParamRule) ValueOr

func (r *Int64ParamRule) ValueOr(defaultValue int64) int64

ValueOr 获取值,如果解析失败则返回默认值

type IntParamRule

type IntParamRule struct {
	// contains filtered or unexported fields
}

IntParamRule 整数参数规则

func (*IntParamRule) In

func (r *IntParamRule) In(values ...int) *IntParamRule

In 枚举值验证

func (*IntParamRule) Max

func (r *IntParamRule) Max(max int) *IntParamRule

Max 最大值验证

func (*IntParamRule) Min

func (r *IntParamRule) Min(min int) *IntParamRule

Min 最小值验证

func (*IntParamRule) NonNegative

func (r *IntParamRule) NonNegative() *IntParamRule

NonNegative 非负数验证(大于等于 0)

func (*IntParamRule) Optional

func (r *IntParamRule) Optional() *IntParamRule

Optional 可选参数

func (*IntParamRule) Positive

func (r *IntParamRule) Positive() *IntParamRule

Positive 正数验证(大于 0)

func (*IntParamRule) Range

func (r *IntParamRule) Range(min, max int) *IntParamRule

Range 范围验证

func (*IntParamRule) Required

func (r *IntParamRule) Required() *IntParamRule

Required 必填验证

func (*IntParamRule) Value

func (r *IntParamRule) Value() int

Value 获取验证后的值

func (*IntParamRule) ValueOr

func (r *IntParamRule) ValueOr(defaultValue int) int

ValueOr 获取值,如果解析失败或为空则返回默认值

type JsonResult

type JsonResult struct {
	StatusCode int
	Data       interface{}
}

JsonResult 表示自定义 JSON 响应。

func (JsonResult) ExecuteResult

func (r JsonResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type M

type M map[string]interface{}

M 是 map[string]interface{} 的简写,类似于 gin.H。 提供了一种方便的方式来创建 map 响应,而无需输入完整的类型签名。

示例:

return web.Ok(web.M{
    "name": "John",
    "age": 30,
    "active": true,
})

type NoContentResult

type NoContentResult struct{}

NoContentResult 表示 204 No Content 响应。

func (NoContentResult) ExecuteResult

func (r NoContentResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type OkResult

type OkResult struct {
	Data interface{}
}

OkResult 表示 200 OK 响应。

func (OkResult) ExecuteResult

func (r OkResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type ParamChain

type ParamChain[T any] struct {
	// contains filtered or unexported fields
}

ParamChain 参数验证链,支持泛型和链式调用。

使用示例:

id := web.Path[int](c, "id").Min(1).Required().Value()
page := web.Query[int](c, "page").Default(1)
email := web.Query[string](c, "email").Required().Email().Value()

func Form

func Form[T any](c *HttpContext, key string) *ParamChain[T]

Form 获取表单参数并转换为指定类型 T。 表单参数默认为可选。

使用示例:

username := web.Form[string](c, "username").Required().MinLength(3).Value()
func Header[T any](c *HttpContext, key string) *ParamChain[T]

Header 获取请求头并转换为指定类型 T。 请求头默认为可选。

使用示例:

token := web.Header[string](c, "Authorization").Required().MinLength(10).Value()

func Path

func Path[T any](c *HttpContext, key string) *ParamChain[T]

Path 获取路径参数并转换为指定类型 T。 路径参数默认为必填。

使用示例:

id := web.Path[int](c, "id").Min(1).Value()

func Query

func Query[T any](c *HttpContext, key string) *ParamChain[T]

Query 获取查询参数并转换为指定类型 T。 查询参数默认为可选。

使用示例:

page := web.Query[int](c, "page").Default(1)
email := web.Query[string](c, "email").Required().Email().Value()

func (*ParamChain[T]) Custom

func (p *ParamChain[T]) Custom(fn func(T) error) *ParamChain[T]

Custom 使用自定义验证函数。

使用示例:

age := web.Query[int](c, "age").Custom(func(v int) error {
    if v < 18 || v > 120 {
        return errors.New("年龄必须在 18-120 之间")
    }
    return nil
})

// Min/Max 验证示例
page := web.Query[int](c, "page").Custom(func(v int) error {
    if v < 1 {
        return errors.New("不能小于 1")
    }
    if v > 100 {
        return errors.New("不能大于 100")
    }
    return nil
}).Value()

// 字符串长度验证示例
username := web.Query[string](c, "username").Custom(func(v string) error {
    if len(v) < 3 {
        return errors.New("长度不能少于 3 个字符")
    }
    if len(v) > 20 {
        return errors.New("长度不能超过 20 个字符")
    }
    return nil
}).Value()

func (*ParamChain[T]) Default

func (p *ParamChain[T]) Default(defaultValue T) T

Default 返回参数值,如果参数不存在或解析失败则返回默认值。 此方法会忽略所有验证错误,直接返回默认值。

使用示例:

page := web.Query[int](c, "page").Default(1)

func (*ParamChain[T]) Get

func (p *ParamChain[T]) Get() (T, error)

Get 返回参数值和标准 error。 使用此方法可以手动处理验证错误(返回自定义错误消息)。

使用示例:

id, err := web.Path[int](c, "id").Min(1).Get()
if err != nil {
    return c.BadRequest("ID 无效: " + err.Error())
}

func (*ParamChain[T]) HasValue

func (p *ParamChain[T]) HasValue() bool

HasValue 检查参数是否有值(是否成功解析)。

func (*ParamChain[T]) Optional

func (p *ParamChain[T]) Optional() *ParamChain[T]

Optional 显式标记参数为可选(通常不需要调用,query/header 默认就是可选的)。

func (*ParamChain[T]) Required

func (p *ParamChain[T]) Required() *ParamChain[T]

Required 标记参数为必填。 如果参数为空或解析失败,将添加验证错误。

func (*ParamChain[T]) Value

func (p *ParamChain[T]) Value() (T, IActionResult)

Value 获取参数值,如果有验证错误则返回错误响应。 返回 (值, IActionResult),如果验证成功则 IActionResult 为 nil。

使用示例:

id, err := web.Path[int](c, "id").Min(1).Value()
if err != nil {
    return err  // 立即返回验证错误
}
// 继续执行业务逻辑

func (*ParamChain[T]) ValueOr

func (p *ParamChain[T]) ValueOr(defaultValue T) T

ValueOr 是 Default 的别名,提供更直观的语义。

type ParamValidator deprecated

type ParamValidator struct {
	// contains filtered or unexported fields
}

ParamValidator 参数验证器,支持链式调用

Deprecated: 使用新的泛型参数 API 代替:web.Path[T], web.Query[T], web.Header[T]

迁移示例:

// 旧 API:
params := c.Params()
id := params.PathInt("id").Min(1).Value()
page := params.QueryInt("page").ValueOr(1)
email := params.QueryString("email").Required().Email().Value()
if result := params.Check(); result != nil { return result }

// 新 API:
id := web.Path[int](c, "id").Min(1).Value()
page := web.Query[int](c, "page").Default(1)
email := web.Query[string](c, "email").Required().Email().Value()
// 不需要手动 Check(),验证错误会自动处理

func (*ParamValidator) Check

func (v *ParamValidator) Check() IActionResult

Check 检查所有验证规则,如果有错误返回 ValidationBadRequest 结果

func (*ParamValidator) Errors

Errors 获取所有验证错误

func (*ParamValidator) HeaderInt

func (v *ParamValidator) HeaderInt(key string) *IntParamRule

HeaderInt 获取并验证 header 整数参数

func (*ParamValidator) HeaderString

func (v *ParamValidator) HeaderString(key string) *StringParamRule

HeaderString 获取并验证 header 字符串参数

func (*ParamValidator) IsValid

func (v *ParamValidator) IsValid() bool

IsValid 检查是否所有验证都通过

func (*ParamValidator) PathInt

func (v *ParamValidator) PathInt(key string) *IntParamRule

PathInt 获取并验证 path 整数参数

func (*ParamValidator) PathInt64

func (v *ParamValidator) PathInt64(key string) *Int64ParamRule

PathInt64 获取并验证 path int64 参数

func (*ParamValidator) PathString

func (v *ParamValidator) PathString(key string) *StringParamRule

PathString 获取并验证 path 字符串参数

func (*ParamValidator) QueryBool

func (v *ParamValidator) QueryBool(key string) *BoolParamRule

QueryBool 获取并验证 query 布尔参数

func (*ParamValidator) QueryFloat

func (v *ParamValidator) QueryFloat(key string) *FloatParamRule

QueryFloat 获取并验证 query 浮点数参数

func (*ParamValidator) QueryInt

func (v *ParamValidator) QueryInt(key string) *IntParamRule

QueryInt 获取并验证 query 整数参数

func (*ParamValidator) QueryInt64

func (v *ParamValidator) QueryInt64(key string) *Int64ParamRule

QueryInt64 获取并验证 query int64 参数

func (*ParamValidator) QueryString

func (v *ParamValidator) QueryString(key string) *StringParamRule

QueryString 获取并验证 query 字符串参数

type RedirectResult

type RedirectResult struct {
	StatusCode int
	Location   string
}

RedirectResult 表示重定向响应。

func (RedirectResult) ExecuteResult

func (r RedirectResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type StaticFileOptions

type StaticFileOptions struct {
	RequestPath string
	FileSystem  string
}

StaticFileOptions 表示静态文件服务选项。

type StatusResult

type StatusResult struct {
	StatusCode int
}

StatusResult 表示仅包含状态码的响应。

func (StatusResult) ExecuteResult

func (r StatusResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type StringParamRule

type StringParamRule struct {
	// contains filtered or unexported fields
}

StringParamRule 字符串参数规则

func (*StringParamRule) Alpha

func (r *StringParamRule) Alpha() *StringParamRule

Alpha 只允许字母

func (*StringParamRule) AlphaNumeric

func (r *StringParamRule) AlphaNumeric() *StringParamRule

AlphaNumeric 只允许字母和数字

func (*StringParamRule) Email

func (r *StringParamRule) Email() *StringParamRule

Email 邮箱格式验证

func (*StringParamRule) In

func (r *StringParamRule) In(values ...string) *StringParamRule

In 枚举值验证

func (*StringParamRule) Length

func (r *StringParamRule) Length(min, max int) *StringParamRule

Length 长度范围验证

func (*StringParamRule) MaxLength

func (r *StringParamRule) MaxLength(max int) *StringParamRule

MaxLength 最大长度验证

func (*StringParamRule) MinLength

func (r *StringParamRule) MinLength(min int) *StringParamRule

MinLength 最小长度验证

func (*StringParamRule) NotEmpty

func (r *StringParamRule) NotEmpty() *StringParamRule

NotEmpty 非空验证(与 Required 类似,但语义更清晰)

func (*StringParamRule) NotIn

func (r *StringParamRule) NotIn(values ...string) *StringParamRule

NotIn 不在枚举值中

func (*StringParamRule) Optional

func (r *StringParamRule) Optional() *StringParamRule

Optional 标记为可选参数

func (*StringParamRule) Pattern

func (r *StringParamRule) Pattern(pattern, message string) *StringParamRule

Pattern 正则表达式验证

func (*StringParamRule) Required

func (r *StringParamRule) Required() *StringParamRule

Required 必填验证

func (*StringParamRule) URL

func (r *StringParamRule) URL() *StringParamRule

URL 网址格式验证

func (*StringParamRule) Value

func (r *StringParamRule) Value() string

Value 获取验证后的值

func (*StringParamRule) ValueOr

func (r *StringParamRule) ValueOr(defaultValue string) string

ValueOr 获取值,如果为空则返回默认值

type ValidationErrorResult

type ValidationErrorResult struct {
	StatusCode int
	Errors     validation.ValidationErrors
}

ValidationErrorResult 表示验证错误响应。

func (ValidationErrorResult) ExecuteResult

func (r ValidationErrorResult) ExecuteResult(c *gin.Context)

ExecuteResult 实现 IActionResult 接口。

type WebApplication

type WebApplication struct {
	Services    di.IServiceProvider // ✅ 直接暴露,强类型
	Environment hosting.IHostEnvironment
	// contains filtered or unexported fields
}

WebApplication 表示已配置的 Web 应用程序。

func (*WebApplication) DELETE

func (app *WebApplication) DELETE(pattern string, handlers ...Handler) router.IEndpointConventionBuilder

DELETE 注册 DELETE 端点。 处理器必须是 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) GET

func (app *WebApplication) GET(pattern string, handlers ...Handler) router.IEndpointConventionBuilder

GET 注册 GET 端点。 处理器必须是 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) GetRoutes

func (app *WebApplication) GetRoutes() []*router.RouteBuilder

GetRoutes 返回所有已注册的路由。

func (*WebApplication) Group

func (app *WebApplication) Group(prefix string, handlers ...Handler) *router.RouteGroupBuilder

Group 创建路由组。 支持 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) MapControllers

func (app *WebApplication) MapControllers() *WebApplication

MapControllers 发现并注册所有控制器为单例。 每个控制器在启动时创建一次,并在应用程序的整个生命周期内使用。 在调用此方法之前,必须使用 AddController() 注册控制器。

此方法应在 Build() 之后和 Run() 之前调用。 对应 .NET 的 app.MapControllers()。

用法:

app := builder.Build()
app.MapControllers()  // 控制器在此处作为单例创建
app.Run()

func (*WebApplication) PATCH

func (app *WebApplication) PATCH(pattern string, handlers ...Handler) router.IEndpointConventionBuilder

PATCH 注册 PATCH 端点。 处理器必须是 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) POST

func (app *WebApplication) POST(pattern string, handlers ...Handler) router.IEndpointConventionBuilder

POST 注册 POST 端点。 处理器必须是 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) PUT

func (app *WebApplication) PUT(pattern string, handlers ...Handler) router.IEndpointConventionBuilder

PUT 注册 PUT 端点。 处理器必须是 ActionHandlerFunc: func(*HttpContext) IActionResult

func (*WebApplication) Run

func (app *WebApplication) Run(urls ...string) error

Run 运行 Web 应用程序并阻塞直到关闭。 如果提供了 urls 参数,它们将覆盖配置的监听地址。 对应 .NET 的 app.Run(url)。

func (*WebApplication) RunWithContext

func (app *WebApplication) RunWithContext(ctx context.Context) error

RunWithContext 使用自定义上下文运行 Web 应用程序并阻塞直到关闭。

func (*WebApplication) Start

func (app *WebApplication) Start(ctx context.Context) error

Start 启动 Web 应用程序。

func (*WebApplication) Stop

func (app *WebApplication) Stop(ctx context.Context) error

Stop 停止 Web 应用程序。

func (*WebApplication) Use

func (app *WebApplication) Use(middleware ...gin.HandlerFunc)

Use 向管道添加中间件。

func (*WebApplication) UseCors

func (app *WebApplication) UseCors(configure ...func(*CorsOptions)) *WebApplication

UseCors 向应用程序添加 CORS 中间件。 对应 .NET 的 app.UseCors()。

func (*WebApplication) UseDefaultFiles

func (app *WebApplication) UseDefaultFiles() *WebApplication

UseDefaultFiles 启用默认文件映射。 对应 .NET 的 app.UseDefaultFiles()。

func (*WebApplication) UseStaticFiles

func (app *WebApplication) UseStaticFiles(configure ...func(*StaticFileOptions)) *WebApplication

UseStaticFiles 提供静态文件服务。 对应 .NET 的 app.UseStaticFiles()。

type WebApplicationBuilder

type WebApplicationBuilder struct {
	Services      di.IServiceCollection
	Configuration config.IConfigurationManager
	Environment   hosting.IHostEnvironment
	Host          *ConfigureHostBuilder
	WebHost       *ConfigureWebHostBuilder
	// contains filtered or unexported fields
}

WebApplicationBuilder is a builder for web applications. Corresponds to .NET WebApplicationBuilder.

func CreateBuilder

func CreateBuilder(args ...string) *WebApplicationBuilder

CreateBuilder creates a new web application builder. Corresponds to .NET WebApplication.CreateBuilder(args).

func (*WebApplicationBuilder) AddControllers

func (b *WebApplicationBuilder) AddControllers(configure ...func(*ControllerOptions)) *WebApplicationBuilder

AddControllers 添加 MVC 控制器服务并启用控制器发现。 TODO: 此方法尚未使用。 对应 .NET 的 services.AddControllers()。

func (*WebApplicationBuilder) AddCors

func (b *WebApplicationBuilder) AddCors(configure ...func(*CorsOptions)) *WebApplicationBuilder

AddCors 向服务集合添加 CORS 服务。 对应 .NET 的 services.AddCors()。

func (*WebApplicationBuilder) Build

Build builds the web application.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL