3、参数校验失败场景分析

在异步导出接口中,参数校验失败是触发频率最高的错误类型。与同步接口不同,异步导出在参数校验失败时,系统尚未创建导出任务,因此响应中不应包含 taskId 或 exportUrl。本节将四种典型校验失败场景拆解为独立分析,帮助设计者在 OpenAPI 规范中精准定义每种场景的响应结构。

3.1 必填参数缺失

必填参数缺失是最基础的校验失败场景。在异步导出中,常见的必填参数包括 exportType(导出类型)、format(文件格式)以及业务标识如 projectId。当请求体中缺少这些字段时,API 应返回 400 Bad Request,并在响应体中明确指明缺失的字段路径。

场景 缺失字段 HTTP 状态码 响应示例(精简)
未指定导出类型 exportType 400 "missing": ["exportType"]
未指定文件格式 format 400 "missing": ["format"]
未指定业务项目 projectId 400 "missing": ["projectId"]
设计要点: 必填参数缺失的响应中,error.code 建议统一为 VALIDATION_MISSING_REQUIRED,便于客户端按 code 做统一处理,而非解析自然语言描述。

3.2 参数类型错误

当传入的参数值与 OpenAPI 规范中定义的 type 不匹配时,触发类型错误。例如 exportType 期望 string 但传入 integer,或 pageSize 期望 integer 但传入 string。类型错误在异步导出中尤其需要关注,因为导出参数往往涉及枚举值或数值范围。

// 类型错误示例:exportType 应为 string,实际传入 integer
POST /api/v1/exports
Content-Type: application/json

{
  "exportType": 12345,
  "format": "csv",
  "projectId": "proj-abc"
}

// 响应
{
  "error": {
    "code": "VALIDATION_TYPE_ERROR",
    "message": "参数类型错误",
    "details": [
      {
        "field": "exportType",
        "expectedType": "string",
        "actualValue": 12345,
        "actualType": "integer"
      }
    ]
  }
}
建议: 在 details 数组中同时返回 expectedType 和 actualType,帮助前端开发者在开发阶段快速定位类型不匹配的根源。

3.3 参数格式错误

格式错误通常发生在字符串类型参数上,例如日期格式、邮箱格式、UUID 格式或自定义枚举值格式。在异步导出中,dateRange(日期范围)和 sortBy(排序字段)是格式错误的高发区。

参数 期望格式 错误示例 错误原因
dateRange.start YYYY-MM-DD "2024/01/01" 分隔符错误,应为 -
dateRange.end YYYY-MM-DD "01-01-2024" 顺序错误,应为年-月-日
exportType 枚举值:user_report、order_report "userReport" 大小写/命名风格不匹配
projectId UUID v4 格式 "proj-abc-123" 不符合 UUID 正则模式
注意: 格式错误与类型错误的区别在于:类型错误是数据类型不匹配(如 string vs integer),格式错误是数据类型正确但字符串内容不符合约束模式(如 pattern、enum、format)。在响应中应使用不同的 code 区分,避免客户端混淆。

3.4 参数范围越界

范围越界包括数值范围(如 pageSize 超过最大限制)、字符串长度范围(如 fileName 超过 255 字符)以及数组元素个数范围(如 selectedIds 超过 1000 个)。在异步导出中,pageSize 和 maxExportRows 是范围越界的典型参数。

// 范围越界示例:pageSize 超过最大允许值 1000
POST /api/v1/exports
Content-Type: application/json

{
  "exportType": "order_report",
  "format": "xlsx",
  "pageSize": 5000
}

// 响应
{
  "error": {
    "code": "VALIDATION_OUT_OF_RANGE",
    "message": "参数值超出允许范围",
    "details": [
      {
        "field": "pageSize",
        "value": 5000,
        "constraints": {
          "minimum": 1,
          "maximum": 1000
        }
      }
    ]
  }
}
设计要点: 范围越界的响应中,details 应包含 constraints 对象,明确告知客户端当前参数的上下界。这比仅返回“超出范围”的文本描述更具可操作性,客户端可直接用约束值做前端校验。
参数校验失败场景分类与响应映射 必填参数缺失 400 Bad Request 参数类型错误 400 Bad Request 参数格式错误 400 Bad Request 参数范围越界 400 Bad Request 统一响应结构(error 对象) code message details[] 无 taskId / exportUrl 关键设计原则 • 四种场景均返回 400 Bad Request,不创建导出任务 • 响应中不包含 taskId、exportUrl 等任务相关字段 • details 数组提供字段级错误定位,支持多字段同时校验

3.5 四种场景的响应差异对比

下表从 code、details 结构、典型约束字段三个维度对比四种校验失败场景,便于在 OpenAPI 规范中为每种场景定义独立的 response 对象。

场景 推荐 error.code details 关键字段 典型约束字段
必填参数缺失 VALIDATION_MISSING_REQUIRED field(缺失字段路径) 无
参数类型错误 VALIDATION_TYPE_ERROR field、expectedType、actualType 无
参数格式错误 VALIDATION_FORMAT_ERROR field、expectedFormat、actualValue pattern、enum、format
参数范围越界 VALIDATION_OUT_OF_RANGE field、value、constraints minimum、maximum、minLength、maxLength
实践建议: 在 OpenAPI 3.0 中,建议为每种校验场景定义一个 schema 组件(如 ValidationMissingRequired、ValidationTypeError),并在 400 响应的 oneOf 中引用它们。这样既保持了规范的精确性,又避免了响应结构的过度泛化。