我有ServerA公开客户端的API方法,如下所示:
def methodExposed()= Action.async(json) { req =>
val reqAsModel = request.body.extractOpt[ClientRequestModel]
reqAsModel match {
case Some(clientRequest) =>
myApiService
.doSomething(clientRequest.someList)
.map(res => ???)
case None =>
Future.successful(BadRequest("could not extract request"))
}
}
所以,我有一个客户端请求的case类,如果我不能从请求体中提取它,那么我返回一个带有消息的BadRequest,否则我调用内部apiService来执行这个请求的一些操作.
doSomething执行对ServerB的API调用,可以返回3个可能的响应:
> 200状态
>我需要提取到案例类的400个身体状态
> 500状态
doSomething看起来像这样:
def doSomething(list: List[String]) = {
wSClient.url(url).withHeaders(("Content-Type", "application/json")).post(write(list)).map { response =>
response.status match {
case Status.BAD_REQUEST =>
parse(response.body).extract[ServiceBResponse]
case Status.INTERNAL_SERVER_ERROR =>
val ex = new RuntimeException(s"ServiceB Failed with status: ${response.status} body: ${response.body}")
throw ex
}
}
}
现在我有两个问题:
>由于200返回没有正文,400有一个正文,我不知道什么应该是doSomething的返回类型
>我应该如何在控制器中处理这个并在methodExposed中正确地将响应返回给客户端?
最佳答案 如果400是常见的预期错误,我认为类型Future [要么[Your400CaseClass,Unit]]才有意义.就methodExposed如何将结果返回给客户端而言,取决于您的业务逻辑:
>客户应该被告知的基础400件事情是什么?如果doSomething遇到400时,methodExposed应该向客户端返回500
>否则,您可以将错误传播到客户端.根据业务逻辑,您可能希望也可能不希望将案例类转换为另一种形式,并可能使用不同的http代码.
如果doSomething返回500(或更一般地,任何意外的http代码),则应该抛出异常(使用Future.failed).
(最后,我希望你没有使用500来传递’正常’错误,如验证/身份验证错误.5xx代码只应用于异常和不可恢复的错误.我知道的大多数http客户端会在5xx时立即抛出异常遇到了,这意味着用户将无法处理它)