RRuna

请求与响应

强类型输入输出和常见响应方式

Runa 支持普通 handler,也支持强类型 Input / Output handler。新手可以先用普通 handler 跑通接口,业务接口变多后再使用强类型写法。

普通 Handler

route.Default().Get("/", func(ctx *route.Context) error {
    return ctx.Text("ok")
})

普通 handler 的签名是:

func(ctx *route.Context) error

它最直接,适合首页、健康检查、简单回调。

强类型输入

type ListUsersInput struct {
    Page int    `query:"page" default:"1"`
    Size int    `query:"size" default:"20"`
    Name string `query:"name"`
}

常见来源:

tag 来源 示例
param 路径参数 /users/{id}
query 查询参数 ?page=1
json JSON body POST JSON
form 表单 application/x-www-form-urlencoded
header Header X-Token
cookie Cookie session_id
default 默认值 没传时使用默认值

parampath 都可以读取路径参数,文档里统一推荐 param

强类型输出

type UserOutput struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

route.Get[ListUsersInput, []UserOutput](
    route.Default(),
    "/users",
    func(ctx *route.Context, input *ListUsersInput) (*[]UserOutput, error) {
        users := []UserOutput{{ID: "1", Name: "Runa"}}
        return &users, nil
    },
)

强类型 handler 返回的是输出对象指针和错误。没有错误时,Runa 会自动把输出渲染成响应。

输入验证

输入结构体可以实现 Validate

type CreateUserInput struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func (input *CreateUserInput) Validate(v *validate.Validator) {
    v.Field("Name").Required("请输入名称").MinLen(2, "名称至少 2 个字符")
    v.Field("Email").Required("请输入邮箱").Email("邮箱格式不正确")
}

强类型路由会在绑定输入后自动执行验证。

常见响应

return ctx.Text("ok")
return ctx.HTML("<h1>ok</h1>")
return ctx.JSON(runa.Map{"ok": true})
return ctx.Blob("application/octet-stream", body)

状态码

路由可以设置成功状态码:

route.Default().Post("/users", createUser).Status(201)

handler 里也可以按当前响应设置:

return ctx.Status(201).JSON(runa.Map{"created": true})

什么时候用哪种写法

场景 推荐写法
健康检查、简单文本 普通 handler
业务 API 强类型 Input / Output
需要 OpenAPI 强类型 Input / Output
需要验证请求字段 强类型 Input + Validate

常见错误

字段没有绑定成功

确认结构体字段是导出的,也就是首字母大写。name string 不能被反射设置,应该写成 Name string

tag 写错位置

路径参数用 param:"id",查询参数用 query:"page",JSON body 用 json:"name"

编辑此页