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

当JSON值不符合要求时,如何返回友好的API错误信息?

如何在API参数校验不通过时返回友好错误信息

问题背景

我的API在正常请求(JSON与case class匹配)时能正常工作,但当JSON不符合业务校验规则时,不知道怎么返回友好的错误提示。

定义的请求Case Class

case class UpdateUserRequest (
   registrationStatus: String,
   level: Int
)

业务校验规则

  • level值必须在10到20之间
  • registrationStatus的取值只能是"a"、"b"或"c"

当前API路由代码

case updateUser @ PUT -> Root / "users" as user => {
    for {
        updateReq <- updateUser.req.as[UpdateUserRequest]
        // 后续业务逻辑
        apiResponse <- Ok(200, true, "")
    } yield apiResponse
}

自定义响应对象

case class ApiResponse(
  statusCode: Int,
  success: Boolean,
  errorMessage: String
)

解决方案

1. 给请求类添加校验逻辑

直接在UpdateUserRequest中嵌入校验方法,返回具体的错误信息列表:

case class UpdateUserRequest(registrationStatus: String, level: Int) {
  // 执行所有规则校验,返回错误信息集合
  def validate: List[String] = {
    val errors = scala.collection.mutable.ListBuffer[String]()
    
    // 校验registrationStatus的合法取值
    if (!List("a", "b", "c").contains(registrationStatus)) {
      errors += s"registrationStatus只能是'a'、'b'或'c',当前值为$registrationStatus"
    }
    
    // 校验level的范围
    if (level < 10 || level > 20) {
      errors += s"level必须在10到20之间,当前值为$level"
    }
    
    errors.toList
  }
}

2. 在路由中处理校验结果

修改路由逻辑,先解析请求,再执行校验,根据校验结果返回对应响应:

case updateUser @ PUT -> Root / "users" as user => {
  updateUser.req.as[UpdateUserRequest].flatMap { updateReq =>
    updateReq.validate match {
      // 校验通过,执行业务逻辑
      case Nil => 
        // 这里写你的业务处理代码
        Ok(ApiResponse(200, true, ""))
      // 校验失败,返回错误提示
      case errors => 
        BadRequest(ApiResponse(400, false, errors.mkString("; ")))
    }
  }.recover {
    // 捕获JSON解析错误(比如level传了字符串、字段缺失等)
    case e: Exception => 
      BadRequest(ApiResponse(400, false, s"请求格式错误:${e.getMessage}"))
  }
}

3. 可选:用自定义错误类型优化结构化校验

如果需要更清晰的错误分类,可以定义专门的错误类型,方便后续扩展:

// 定义错误类型
sealed trait ValidationError
case class InvalidRegistrationStatus(value: String) extends ValidationError
case class LevelOutOfRange(value: Int) extends ValidationError

// 扩展请求类的校验方法
case class UpdateUserRequest(registrationStatus: String, level: Int) {
  def validate: List[ValidationError] = {
    val errors = scala.collection.mutable.ListBuffer[ValidationError]()
    if (!List("a", "b", "c").contains(registrationStatus)) {
      errors += InvalidRegistrationStatus(registrationStatus)
    }
    if (level < 10 || level > 20) {
      errors += LevelOutOfRange(level)
    }
    errors.toList
  }
}

// 把错误类型转换成友好提示
def errorMessage(errors: List[ValidationError]): String = {
  errors.map {
    case InvalidRegistrationStatus(v) => s"registrationStatus只能是'a'、'b'或'c',当前值为$v"
    case LevelOutOfRange(v) => s"level必须在10到20之间,当前值为$v"
  }.mkString("; ")
}

然后在路由中使用:

case updateUser @ PUT -> Root / "users" as user => {
  updateUser.req.as[UpdateUserRequest].flatMap { updateReq =>
    updateReq.validate match {
      case Nil => 
        // 业务逻辑处理
        Ok(ApiResponse(200, true, ""))
      case errors => 
        BadRequest(ApiResponse(400, false, errorMessage(errors)))
    }
  }.recover {
    case e: Exception => 
      BadRequest(ApiResponse(400, false, s"请求格式错误:${e.getMessage}"))
  }
}

说明

  • 参数校验失败返回400 Bad Request符合REST规范,也可以根据需求调整状态码
  • recover块专门处理JSON解析层面的错误,比如类型不匹配、必填字段缺失等情况
  • 自定义校验逻辑覆盖了业务规则约束,比单纯的JSON类型匹配更全面

内容的提问来源于stack exchange,提问作者Blankman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:55:28