如何通过API对外暴露Go结构体定义的Job参数JSON Schema?
解决方案
核心思路
利用Go的反射机制直接解析任务参数结构体的字段信息,结合json标签生成对应的参数Schema,无需额外维护独立的Schema定义。通过建立job_type与对应参数结构体的映射关系,实现动态生成指定任务类型的参数Schema接口。
实现步骤
1. 建立任务类型与参数结构体的映射
定义全局映射,关联每个job_type到对应的参数结构体类型:
import "reflect" var jobParamTypeMap = map[string]reflect.Type{ "user_refresh": reflect.TypeOf(UserRefreshJobParams{}), // 新增任务时,只需在这里添加对应的结构体类型 }
2. 编写反射解析函数
通过反射遍历结构体字段,提取json标签、字段类型、必填性等信息:
import "strings" func buildParamSchema(t reflect.Type) []map[string]interface{} { var params []map[string]interface{} // 处理指针类型的结构体 if t.Kind() == reflect.Ptr { t = t.Elem() } for i := 0; i < t.NumField(); i++ { field := t.Field(i) jsonTag := field.Tag.Get("json") if jsonTag == "-" { continue // 跳过标记为忽略的字段 } // 解析json标签,拆分字段名和选项 tagParts := strings.Split(jsonTag, ",") fieldName := tagParts[0] isOptional := false // 检查是否包含omitempty选项 for _, opt := range tagParts[1:] { if opt == "omitempty" { isOptional = true break } } // 判断字段类型(支持基础类型,可扩展复杂类型) fieldType := "" fieldKind := field.Type.Kind() // 处理指针类型,取指向的实际类型 if fieldKind == reflect.Ptr { isOptional = true fieldKind = field.Type.Elem().Kind() } switch fieldKind { case reflect.String: fieldType = "string" case reflect.Int, reflect.Int32, reflect.Int64: fieldType = "integer" case reflect.Float32, reflect.Float64: fieldType = "number" case reflect.Bool: fieldType = "boolean" // 可扩展处理切片、嵌套结构体等复杂类型 } params = append(params, map[string]interface{}{ "name": fieldName, "type": fieldType, "required": !isOptional, }) } return params }
3. 实现API端点Handler
编写HTTP处理器,根据请求的job_type参数返回对应的Schema:
import ( "encoding/json" "net/http" ) func JobParamSchemaHandler(w http.ResponseWriter, r *http.Request) { jobType := r.URL.Query().Get("job_type") if jobType == "" { http.Error(w, "缺少job_type查询参数", http.StatusBadRequest) return } paramType, exists := jobParamTypeMap[jobType] if !exists { http.Error(w, "无效的job_type", http.StatusNotFound) return } paramSchema := buildParamSchema(paramType) response := map[string]interface{}{ "job_param_schema": map[string]interface{}{ "job_type": jobType, "job_params": paramSchema, }, } w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(response) }
4. 注册路由
将Handler挂载到指定路由:
http.HandleFunc("/jobs/job_parameter_schemas", JobParamSchemaHandler)
扩展说明
- 复杂类型支持:如果需要处理嵌套结构体、切片等复杂类型,可以在
buildParamSchema函数中添加递归逻辑,解析嵌套字段的Schema。 - 类型映射完善:可以根据业务需求补充更多Go类型到JSON Schema类型的映射,比如
time.Time对应string(格式为date-time)。 - 校验逻辑复用:如果参数结构体中使用了校验标签(如
validate),可以同时提取校验规则(如最小值、正则表达式)加入到Schema中。
内容的提问来源于stack exchange,提问作者DJL
相关产品推荐
相关产品推荐

