Go struct tag 生成

一键生成 json/yaml/db/form/validate tag

424 次访问

Go struct tag 速查

json/yaml/db/form/validate tag · 点击复制

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

API 模型快速对接

后端开发者从数据库表设计转向 API 开发时,需要为 Go 结构体编写 JSON 和 db 标签。手动编写 tags 容易因拼写错误导致序列化失败或 ORM 映射异常。使用本工具,粘贴结构体定义后一键生成 json 和 db 标签,确保字段名称、忽略规则(omitempty)与数据库列名完全对齐,减少联调阶段的低级 bug。

📝

表单验证规则批量注入

Web 应用在处理用户注册、订单提交等场景时,需要对每个字段添加 validate 标签(如 required、min、max、email)。逐个手写 20 个字段的验证规则既耗时又容易遗漏边界条件。通过本工具,在结构体上集中定义验证规则,一键生成所有 validate 标签,保证前端提交的数据在后端被严格校验,避免空值入库或格式错误。

🗄️

ORM 模型与数据库字段同步

使用 GORM、XORM 等 ORM 框架时,结构体字段需要与数据库表列名一一对应,且要处理主键、自增、忽略(-)等特殊标签。当数据库表有 30+ 列时,手动维护 tags 极易出现列名拼写错误或类型不匹配。本工具允许在结构体上直接标注 db 标签,一键生成后与 DDL 脚本交叉验证,确保 ORM 模型与建表语句完全同步。

🔧

微服务间数据契约生成

在微服务架构中,服务间通过 JSON 或 YAML 交换数据,需要为每个 RPC 请求 / 响应定义精确的序列化标签。若某个字段在 A 服务中命名为 user_id,在 B 服务中误写为 UserId,将导致反序列化失败。使用本工具,在共享的 proto 或结构体定义上统一生成 json 和 yaml 标签,保证所有服务使用一致的字段命名规则,消除跨服务数据契约不一致问题。

📚

API 文档自动生成辅助

使用 swaggo 等工具生成 Swagger 文档时,结构体的 json 标签直接影响文档中的字段名和示例值。如果标签不完整或格式错误,生成的 API 文档会显示混乱的字段名(如 UserName 而非 user_name)。通过本工具为所有 DTO 结构体批量生成规范的 json 标签,确保自动生成的 API 文档字段命名与前端预期一致,减少前后端联调时的文档歧义。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具 (go-tag.tl654.com)在线 JSON 生成器 (如 json2go.com)手动编写
数据隐私纯浏览器处理,不上传任何数据需将 struct 代码粘贴到第三方服务器完全本地,无网络传输
处理速度即时生成(毫秒级)受网络延迟影响(1-3秒)取决于开发者打字速度与熟练度
离线可用完全离线(浏览器本地运行)必须联网完全离线
tag 类型覆盖json / yaml / db / form / validate 五种通常仅支持 json 和 yaml支持所有类型,但需手动记忆语法
批量 tag 生成一键生成全部五种 tag每次只能生成一种 tag逐一手动添加,易遗漏或写错
语法正确性自动保证 tag 格式正确依赖工具实现,部分工具格式有偏差依赖开发者经验,易出现拼写错误
学习成本无需学习,输入 struct 直接生成需了解工具界面操作需记忆每种 tag 的键名和格式规范

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例7 个典型场景,覆盖常规、边界与易错

输入输出说明
type User struct { Name string Age int }type User struct { Name string `json:"name" yaml:"name" db:"name" form:"name" validate:"required"` Age int `json:"age" yaml:"age" db:"age" form:"age" validate:"required"` }典型常规场景:基础结构体,所有字段自动生成全部 tag
type Config struct { DebugMode bool `json:"debug_mode"` Port int `json:"port"` }type Config struct { DebugMode bool `json:"debug_mode" yaml:"debug_mode" db:"debug_mode" form:"debug_mode" validate:"required"` Port int `json:"port" yaml:"port" db:"port" form:"port" validate:"required"` }边界 case:输入已含 json tag,工具会保留并补充其他 tag
type EmptyStruct struct { }type EmptyStruct struct { }边界 case:空结构体,工具无字段可处理,原样输出
type User struct { Name string password string }type User struct { Name string `json:"name" yaml:"name" db:"name" form:"name" validate:"required"` password string `json:"password" yaml:"password" db:"password" form:"password" validate:"required"` }易错 case:小写字段名(非导出)也会生成 tag,但 Go 编译会忽略
type Product struct { ID int64 `db:"product_id"` Name string `db:"product_name"` CreatedAt time.Time }type Product struct { ID int64 `json:"id" yaml:"id" db:"product_id" form:"id" validate:"required"` Name string `json:"name" yaml:"name" db:"product_name" form:"name" validate:"required"` CreatedAt time.Time `json:"created_at" yaml:"created_at" db:"created_at" form:"created_at" validate:"required"` }典型场景:部分字段已有 db tag,工具保留并补全其他 tag
type User struct { Email string `validate:"required,email"` Password string `validate:"min=8"` }type User struct { Email string `json:"email" yaml:"email" db:"email" form:"email" validate:"required,email"` Password string `json:"password" yaml:"password" db:"password" form:"password" validate:"min=8"` }边界 case:输入已有 validate tag,工具保留原规则并补全其他 tag
type Response struct { Status int `json:"-"` Data string `json:"data"` }type Response struct { Status int `json:"-" yaml:"-" db:"status" form:"-" validate:"required"` Data string `json:"data" yaml:"data" db:"data" form:"data" validate:"required"` }易错 case:json:"-" 表示忽略,工具对 db/form 仍会生成普通 tag

常见错误对照8 个常踩的坑 · 错误 → 修复

1. JSON 字段名忘了双引号

错误
{name: "Alice", age: 30}
修复
{"name": "Alice", "age": 30}

JSON 规范要求键名必须用双引号包裹。无引号的写法是 JavaScript 对象字面量,不是合法 JSON,Go 的 encoding/json 会解析失败。

2. 单引号代替双引号

错误
{'name': 'Alice', 'age': 30}
修复
{"name": "Alice", "age": 30}

JSON 只接受双引号作为字符串定界符。单引号是 YAML 或 Python dict 的写法,Go 标准库 json.Unmarshal 会直接报语法错误。

3. 数字前补零

错误
{"version": 01.2}
修复
{"version": 1.2}

JSON 数字不允许前导零(除非值是 0)。Go 的 json.Decoder 会拒绝解析 01.2,返回 "invalid syntax" 错误。

4. 布尔值写成小写 true/false 以外的形式

错误
{"active": True} 或 {"active": "true"}
修复
{"active": true}

JSON 布尔值必须是全小写 true/false。Python 的 True 或字符串 "true" 都不被 Go 的 json.Unmarshal 接受,会解析失败或类型错误。

5. YAML 里用 Tab 缩进

错误
name: Alice
	age: 30
修复
name: Alice
  age: 30

YAML 强制使用空格缩进,Tab 会导致解析错误。Go 的 yaml.v3 库会报 "found character that cannot start any token"。建议编辑器设置显示不可见字符。

6. validate tag 里写错约束名

错误
`validate:"max_len=10"`
修复
`validate:"max=10"`

go-playground/validator 使用 max/min 而非 max_len/min_len。写错约束名会被忽略,导致校验不生效,数据可能通过不合法值。

7. form tag 与前端字段名大小写不匹配

错误
前端 POST: `name=Alice`  后端: `form:"Name"`
修复
前端 POST: `name=Alice`  后端: `form:"name"`

Go 的 form 解析默认区分大小写。前端表单字段名通常小写,后端 tag 必须精确匹配,否则绑定到零值。建议统一用小写。

8. db tag 用驼峰命名但数据库列是下划线

错误
`db:"userName"`  (数据库列: user_name)
修复
`db:"user_name"`

大多数数据库(PostgreSQL/MySQL)默认列名小写下划线。Go 结构体字段用驼峰,但 db tag 需显式映射到数据库列名,否则查询失败。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

Tag = `key:"value"`

变量说明

  • Tag — 生成的 struct tag 字符串
  • key — tag 类型(json/yaml/db/form/validate)
  • value — tag 值(字段名/约束条件)

示例

Go 结构体字段 UserName string,生成 json tag:`json:"user_name"`。若同时生成 validate tag:`json:"user_name" validate:"required,min=3"`。

适用范围

适用于 Go 语言 struct 字段的常见 tag 生成,包括 json、yaml、db、form、validate 五种类型。不适用于自定义 tag 或非标准 tag 格式。

原理图

输入 Go 结构体如:type User struct { ... }解析字段与类型提取字段名、类型、嵌套关系纯浏览器 AST 解析生成 Tag 字符串json:"field_name"yaml / db / form / validate输出完整结构体带 Tag 的 Go 代码可一键复制用户选择 Tag 类型勾选 json / yaml / db / form / validate按规则拼接 Tag字段名 → snake_case / camelCase类型 → 对应 validate 规则
用户输入 / 输出 浏览器内处理 Tag 生成

开发者集成

3 种主流语言 · 复制即用

import json

# 模拟 Go struct tag 生成:根据字段名和类型推断常见 tag
fields = [
    ("UserID", "int"),
    ("UserName", "string"),
    ("Email", "string"),
    ("Age", "int"),
]

for name, typ in fields:
    # 驼峰转 snake_case 用于 json/yaml/db tag
    snake = "".join("_" + c.lower() if c.isupper() else c for c in name).lstrip("_")
    json_tag = f'json:"{snake}"'
    yaml_tag = f'yaml:"{snake}"'
    db_tag = f'db:"{snake}"'
    form_tag = f'form:"{snake}"'
    # validate tag 示例:非空 + 邮箱格式(仅 string 类型)
    if typ == "string":
        if "email" in name.lower():
            validate_tag = 'validate:"required,email"'
        else:
            validate_tag = 'validate:"required"'
    else:
        validate_tag = 'validate:"required"'
    print(f"{name} {typ} `{json_tag} {yaml_tag} {db_tag} {form_tag} {validate_tag}`")

# 输出示例:
# UserID int `json:"user_id" yaml:"user_id" db:"user_id" form:"user_id" validate:"required"`
# UserName string `json:"user_name" yaml:"user_name" db:"user_name" form:"user_name" validate:"required"`
# Email string `json:"email" yaml:"email" db:"email" form:"email" validate:"required,email"`
# Age int `json:"age" yaml:"age" db:"age" form:"age" validate:"required"`
package main

import (
	"fmt"
	"reflect"
	"strings"
)

// User 结构体,手动编写 tag 示例
// 实际工具自动生成这些 tag
type User struct {
	UserID   int    `json:"user_id" yaml:"user_id" db:"user_id" form:"user_id" validate:"required"`
	UserName string `json:"user_name" yaml:"user_name" db:"user_name" form:"user_name" validate:"required"`
	Email    string `json:"email" yaml:"email" db:"email" form:"email" validate:"required,email"`
	Age      int    `json:"age" yaml:"age" db:"age" form:"age" validate:"required"`
}

func main() {
	// 反射读取所有字段的 tag
	t := reflect.TypeOf(User{})
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		// 获取 struct tag 中的 json 值
		jsonTag := field.Tag.Get("json")
		// 获取 validate 值
		validateTag := field.Tag.Get("validate")
		fmt.Printf("Field: %s, json: %s, validate: %s\n", field.Name, jsonTag, validateTag)
	}
	// 输出:
	// Field: UserID, json: user_id, validate: required
	// Field: UserName, json: user_name, validate: required
	// Field: Email, json: email, validate: required,email
	// Field: Age, json: age, validate: required

	// 模拟 JSON 序列化
	u := User{UserID: 1, UserName: "Alice", Email: "alice@example.com", Age: 30}
	// 实际使用 encoding/json 包
	_ = u
}
// 模拟 Go struct tag 生成:根据字段名和类型生成 tag 字符串
const fields = [
  { name: 'UserID', type: 'int' },
  { name: 'UserName', type: 'string' },
  { name: 'Email', type: 'string' },
  { name: 'Age', type: 'int' },
];

// 驼峰转 snake_case
function toSnakeCase(str) {
  return str.replace(/[A-Z]/g, (letter, idx) =>
    idx === 0 ? letter.toLowerCase() : '_' + letter.toLowerCase()
  );
}

fields.forEach(({ name, type }) => {
  const snake = toSnakeCase(name);
  const jsonTag = `json:"${snake}"`;
  const yamlTag = `yaml:"${snake}"`;
  const dbTag = `db:"${snake}"`;
  const formTag = `form:"${snake}"`;
  // 简单 validate 推断
  let validateTag = 'validate:"required"';
  if (type === 'string' && name.toLowerCase().includes('email')) {
    validateTag = 'validate:"required,email"';
  }
  console.log(`${name} ${type} \`${jsonTag} ${yamlTag} ${dbTag} ${formTag} ${validateTag}\``);
});

// 输出:
// UserID int `json:"user_id" yaml:"user_id" db:"user_id" form:"user_id" validate:"required"`
// UserName string `json:"user_name" yaml:"user_name" db:"user_name" form:"user_name" validate:"required"`
// Email string `json:"email" yaml:"email" db:"email" form:"email" validate:"required,email"`
// Age int `json:"age" yaml:"age" db:"age" form:"age" validate:"required"`

常见问题

8 个高频疑问

这个工具生成的 tag 能直接用吗?会不会有语法错误?
生成的 tag 遵循 Go 标准库的 struct tag 格式,语法上没有问题。但需要注意:json 和 yaml tag 的字段名默认使用小驼峰(如 UserName → user_name),如果需要特定命名风格(如全小写加下划线),需手动调整。validate tag 使用了 go-playground/validator 的语法(如 required, min=1),如果项目中用的不是这个库,需要自行修改。建议生成后先跑一遍 go vet 检查。
为什么生成的 json tag 和我想的不一样?比如我想用 snake_case 而不是 camelCase?
工具默认使用小驼峰转小写下划线(snake_case)的规则,例如 UserName → user_name。如果希望保留原始字段名或使用其他命名风格,目前需要手动编辑结果区域。未来版本可能会加入命名风格选项。另一种做法是先生成默认 tag,再在 IDE 中用正则替换(例如将 `json:"([a-z]+)_([a-z]+)"` 替换为 `json:"$1_$2"`)来批量调整。
这个工具支持生成 gorm / bson / xml 这些 tag 吗?
当前版本支持 json、yaml、db、form、validate 五种 tag,暂不支持 gorm、bson、xml 等。如果项目中需要这些 tag,可以先用工具生成基础 tag(如 json 和 db),再手动补充 gorm 标签。例如 `gorm:"column:user_name;type:varchar(100)"`。如果团队有高频需求,可以反馈给开发者考虑后续扩展。
生成的 validate tag 能直接用在 Gin 框架里做参数校验吗?
可以。Gin 框架默认使用 go-playground/validator 作为校验引擎,工具生成的 validate tag(如 `validate:"required,min=3,max=50"`)语法与之兼容。但注意:Gin 的 `binding` 标签(如 `binding:"required"`)是 Gin 自己的语法,与 validate tag 不同。如果项目同时使用 Gin 和 validator,建议统一使用 validate tag,并在 Gin 路由中设置 `binding:"-"` 避免冲突。
我输入的 struct 字段有几十个,生成结果会卡吗?
不会。所有处理都在浏览器端用 JavaScript 完成,不经过网络请求。测试过 200+ 字段的 struct,生成时间在 1 秒以内。如果遇到卡顿,通常是浏览器解析大段 JSON 时的渲染延迟(尤其 Chrome 低版本)。建议分批次生成(每次 30-50 个字段),或者使用 Firefox/Edge 浏览器。
生成的 tag 里字段顺序和我输入的不一样,是 bug 吗?
不是 bug。工具在解析 struct 时按字段在源码中的定义顺序输出,但 Go 的 struct 字段顺序本身在反射时是不保证的(虽然实际实现中通常保持一致)。如果顺序对后续代码生成(如数据库迁移)有严格要求,建议在输入 struct 中按期望顺序排列字段。工具不会对字段排序或重排。
这个工具和 VS Code 的 Go struct tag 插件比,哪个好用?
各有侧重。VS Code 插件(如 Go Struct Tag)在编辑器中直接操作,适合写代码时即时生成;本工具是网页版,适合临时需要批量生成或跨平台使用(比如在 CI/CD 流水线或团队协作时分享链接)。本工具的优势是零安装、支持多种 tag 同时生成(json+yaml+db 一次搞定),并且纯前端运行,隐私更安全。建议根据场景选择:写代码用插件,批量/分享用网页。
生成的 db tag 里的字段名和数据库里的列名对不上,怎么办?
db tag 默认使用小写下划线命名(如 UserName → user_name),如果数据库列名是其他风格(如全大写 USER_NAME 或驼峰 userName),需要手动修改 db tag 中的值。工具目前不提供自定义映射规则。建议先确认数据库列名风格,再手动替换。如果项目使用 GORM,也可以利用 GORM 的表名和列名映射配置(如 TableName() 方法)来避免修改每个 tag。
选择 打开 +新窗口 esc关闭