Sri*_*i K 5 validation json scala akka spray-json
当所有输入都有效时,即具有有效的键(包括大小写)和值时,我可以处理此 json。下一步是验证键并在键或值无效时返回 400(错误请求)。添加此验证的好方法是什么?
API调用
POST http://localhost:8080/api/v1/adsession
Content-Type: application/json
body {
"sessionId": "abcd123123123",
"serviceGroup": "1234",
"targetCode": {"zipcodes":"30096,30188","code2":"value2"}
}
Run Code Online (Sandbox Code Playgroud)
路由处理程序
class AdSessionRoutes(services: Services)(implicit ec: ExecutionContext, log: LoggingContext) extends ApiRoute(services) {
implicit val timeout = Timeout(10 seconds)
val postSession = pathPrefix("adsession") & pathEnd & post
val route: Route = {
withService("adSession") { service =>
postSession {
entity(as[AdSession]) { adSession =>
log.info(s"Processing POST ${adSession}")
val future = (service ? CreateAdSession(adSession)).mapTo[AdSession]
onComplete(future) {
case Success(result) =>
complete(StatusCodes.Created, result)
case Failure(e) =>
log.error(s"Error: ${e.toString}")
complete(StatusCodes.InternalServerError, Message(ApiMessages.UnknownException))
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
模型对象
case class AdSession(
sessionId: String,
serviceGroup: String,
targetCodes: Map[String,String],
id: Option[String] = None)
object AdSessionJsonProtocol extends DefaultJsonProtocol {
implicit val adSessionFormat = jsonFormat4(AdSession)
}
Run Code Online (Sandbox Code Playgroud)
entity(as[AdSession]) 确实将键映射到案例类字段,但我不确定如何捕获这些错误。我想捕获这些错误并添加额外的验证并返回 400 与有效的 json 错误响应。
定义您自己read的write方法,AdSession如下所示:
object AdSessionJsonProtocol {
implicit object adSessionJsonFormat extends RootJsonFormat[AdSession] {
override def read(json: JsValue): AdSession = ???
override def write(obj: AdSession): JsValue = ???
}
}
Run Code Online (Sandbox Code Playgroud)
在函数内部read您可以执行额外的验证。
另一个问题是如何将收集到的错误传递给Spray路由。我想建议你换成AdSession,Either[String, AdSession]例如:
postSession {
entity(as[Either[String, AdSession]]) { adSession =>
Run Code Online (Sandbox Code Playgroud)
所以,现在你的adSessionJsonFormat遗嘱是这样的:
implicit object adSessionJsonFormat extends RootJsonFormat[Either[String, AdSession]] {
override def read(json: JsValue): Either[String, AdSession] = {
// json.asJsObject.fields access fields, perform checks
// if everything is OK return Right(AdSession(...))
// otherwise return Lift("Error Message")
}
override def write(obj: Either[String, AdSession]): JsValue = ???
}
Run Code Online (Sandbox Code Playgroud)
但是,我认为可以使用一些隐式魔法以更优雅的方式解决它。
| 归档时间: |
|
| 查看次数: |
2811 次 |
| 最近记录: |