POST 请求有时会在 Akka-http 程序中命中错误的端点
POST request sometimes hits the wrong endpoint in Akka-http program
我有一个 Akka-http 2 服务器来处理 HTTP 请求。
在任一端点上,我正在转换为大小写 class A 或 B:
case class caseClassA(data: String, eventID: String)
case class caseClassB(data: String, otherData: JsObject)
我有一个这样的路由对象:
val routes = {
logRequestResult("akka-http-microservice") {
pathPrefix("some_endpoint")
(post & entity(as[caseClassA])) {
Request =>
val future = someFunction(Request)
complete {
future.map(result =>
result
)
}
} ~
pathPrefix("other_endpoint") {
(post & entity(as[caseClassB])) {
Request =>
val future = otherFunction(Request)
complete {
future.map(result =>
result
)
}
}
}
}
问题:有时,当从 iOS 应用调用时使用 Alamofire,当使用 caseClassB-convertible JSON 对象请求 other_endpoint
时,我收到了错误数据对 some_endpoint
的错误响应:
[DEBUG] [01/22/2016 16:30:16.350] [ReactiveKafka-akka.actor.default-dispatcher-23] [ActorSystem(ReactiveKafka)] akka-http-microservice: Response for
Request : HttpRequest(HttpMethod(POST),http://192.168.2.141:9004/other_endpoint,List(Host: 192.168.2.141:9004, Connection: keep-alive, Accept: */*, User-Agent: myapp/myco.myapp (1; OS Version 9.2 (Build 13C75)), Accept-Language: en-US, zh-Hans-US;q=0.9, Accept-Encoding: gzip, compress;q=0.5),HttpEntity.Strict(application/json,ByteString(XXX, XXX, XXX, XXX, ETC <REPLACED FOR READABILITY, THIS WAS GOOD DATA>)),HttpProtocol(HTTP/1.1))
Response: Complete(HttpResponse(200 OK,List(),HttpEntity.Strict(application/json,ByteString(XXX, XXX, XXX, XXX, ETC <REPLACED FOR READABILITY, THIS WAS GOOD DATA>)),HttpProtocol(HTTP/1.1)))
[DEBUG] [01/22/2016 16:30:21.347] [ReactiveKafka-akka.actor.default-dispatcher-5] [akka://ReactiveKafka/user/$a/flow-17-2-prefixAndTail] Cancelling akka.stream.impl.MultiStreamOutputProcessor$SubstreamOutput@454147bb (after: 5000 ms)
[DEBUG] [01/22/2016 16:30:26.259] [ReactiveKafka-akka.actor.default-dispatcher-7] [ActorSystem(ReactiveKafka)] akka-http-microservice: Response for
Request : HttpRequest(HttpMethod(POST),http://192.168.2.141:9004/other_endpoint,List(Host: 192.168.2.141:9004, Connection: keep-alive, Accept: */*, User-Agent: myapp/myco.myapp (1; OS Version 9.2 (Build 13C75)), Accept-Language: en-US, zh-Hans-US;q=0.9, Accept-Encoding: gzip, compress;q=0.5),HttpEntity.Default(application/json,319,akka.stream.scaladsl.Source@c3e53bd),HttpProtocol(HTTP/1.1))
Response: Rejected(List(MalformedRequestContentRejection(Object is missing required member 'eventID',Some(java.util.NoSuchElementException: key not found: eventID)), TransformationRejection(<function1>), MalformedRequestContentRejection(Unexpected end-of-input at input index 0 (line 1, position 1), expected JSON Value:
^
,None), TransformationRejection(<function1>)))
如您所见,缺少 eventID
,这是在尝试转换为 caseClassA。上面输出中的两个请求都显示我正在尝试点击 other_endpoint。当我使用相同的数据从 Postman 调用此端点时,它在 100% 的时间内都有效。
什么给了?
如上面的评论所示,问题是 "some_endpoint"
的代码周围缺少大括号 ({}
)。这是更正后的代码块:
val routes = {
logRequestResult("akka-http-microservice") {
pathPrefix("some_endpoint") {
(post & entity(as[caseClassA])) {
Request =>
val future = someFunction(Request)
complete {
future.map(result =>
result
)
}
}
} ~
pathPrefix("other_endpoint") {
(post & entity(as[caseClassB])) {
Request =>
val future = otherFunction(Request)
complete {
future.map(result =>
result
)
}
}
}
}
我有一个 Akka-http 2 服务器来处理 HTTP 请求。
在任一端点上,我正在转换为大小写 class A 或 B:
case class caseClassA(data: String, eventID: String)
case class caseClassB(data: String, otherData: JsObject)
我有一个这样的路由对象:
val routes = {
logRequestResult("akka-http-microservice") {
pathPrefix("some_endpoint")
(post & entity(as[caseClassA])) {
Request =>
val future = someFunction(Request)
complete {
future.map(result =>
result
)
}
} ~
pathPrefix("other_endpoint") {
(post & entity(as[caseClassB])) {
Request =>
val future = otherFunction(Request)
complete {
future.map(result =>
result
)
}
}
}
}
问题:有时,当从 iOS 应用调用时使用 Alamofire,当使用 caseClassB-convertible JSON 对象请求 other_endpoint
时,我收到了错误数据对 some_endpoint
的错误响应:
[DEBUG] [01/22/2016 16:30:16.350] [ReactiveKafka-akka.actor.default-dispatcher-23] [ActorSystem(ReactiveKafka)] akka-http-microservice: Response for
Request : HttpRequest(HttpMethod(POST),http://192.168.2.141:9004/other_endpoint,List(Host: 192.168.2.141:9004, Connection: keep-alive, Accept: */*, User-Agent: myapp/myco.myapp (1; OS Version 9.2 (Build 13C75)), Accept-Language: en-US, zh-Hans-US;q=0.9, Accept-Encoding: gzip, compress;q=0.5),HttpEntity.Strict(application/json,ByteString(XXX, XXX, XXX, XXX, ETC <REPLACED FOR READABILITY, THIS WAS GOOD DATA>)),HttpProtocol(HTTP/1.1))
Response: Complete(HttpResponse(200 OK,List(),HttpEntity.Strict(application/json,ByteString(XXX, XXX, XXX, XXX, ETC <REPLACED FOR READABILITY, THIS WAS GOOD DATA>)),HttpProtocol(HTTP/1.1)))
[DEBUG] [01/22/2016 16:30:21.347] [ReactiveKafka-akka.actor.default-dispatcher-5] [akka://ReactiveKafka/user/$a/flow-17-2-prefixAndTail] Cancelling akka.stream.impl.MultiStreamOutputProcessor$SubstreamOutput@454147bb (after: 5000 ms)
[DEBUG] [01/22/2016 16:30:26.259] [ReactiveKafka-akka.actor.default-dispatcher-7] [ActorSystem(ReactiveKafka)] akka-http-microservice: Response for
Request : HttpRequest(HttpMethod(POST),http://192.168.2.141:9004/other_endpoint,List(Host: 192.168.2.141:9004, Connection: keep-alive, Accept: */*, User-Agent: myapp/myco.myapp (1; OS Version 9.2 (Build 13C75)), Accept-Language: en-US, zh-Hans-US;q=0.9, Accept-Encoding: gzip, compress;q=0.5),HttpEntity.Default(application/json,319,akka.stream.scaladsl.Source@c3e53bd),HttpProtocol(HTTP/1.1))
Response: Rejected(List(MalformedRequestContentRejection(Object is missing required member 'eventID',Some(java.util.NoSuchElementException: key not found: eventID)), TransformationRejection(<function1>), MalformedRequestContentRejection(Unexpected end-of-input at input index 0 (line 1, position 1), expected JSON Value:
^
,None), TransformationRejection(<function1>)))
如您所见,缺少 eventID
,这是在尝试转换为 caseClassA。上面输出中的两个请求都显示我正在尝试点击 other_endpoint。当我使用相同的数据从 Postman 调用此端点时,它在 100% 的时间内都有效。
什么给了?
如上面的评论所示,问题是 "some_endpoint"
的代码周围缺少大括号 ({}
)。这是更正后的代码块:
val routes = {
logRequestResult("akka-http-microservice") {
pathPrefix("some_endpoint") {
(post & entity(as[caseClassA])) {
Request =>
val future = someFunction(Request)
complete {
future.map(result =>
result
)
}
}
} ~
pathPrefix("other_endpoint") {
(post & entity(as[caseClassB])) {
Request =>
val future = otherFunction(Request)
complete {
future.map(result =>
result
)
}
}
}
}