You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:25:55