나는 당신이하려고하는 것에 대한 일반적인 해결책을 제공 할 수 있다고 생각합니다. 당신은 다음과 같이 Route
을 반환하는 방법을 작성하여 시작할 수 있습니다
def service[T:ClassTag](actor:ActorRef, command:Any)
(implicit timeout:Timeout, _marshaller: ToResponseMarshaller[T]):Route = {
val fut = (actor ? command).mapTo[ServiceResponse]
onComplete(fut){
case util.Success(ir:InvalidRequest) =>
complete(StatusCodes.BadRequest, ir)
case util.Success(t:T) =>
complete(t)
case util.Failure(ex) =>
complete(StatusCodes.InternalServerError)
}
}
이 방법은 제공된 배우에 요청을 발사 요청을 통해, 그 결과를 나타내는 Future
을 가져옵니다. 그런 다음 onComplete
지시문을 사용하여 InvalidResponse
케이스에 특수 처리를 적용합니다. 여기에서 중요한 것은 성공 사례에 필요한 범위 내에서 암시 적으로 ToResponseMarshaller[T]
이 범위에 있음을 의미합니다.
그럼, 다음과 같은 클래스와 포맷터 정의했다 가정 해 봅시다 :
trait ServiceResponse
case class Foo(id:Int) extends ServiceResponse
implicit val fooFormat = jsonFormat1(Foo)
case class InvalidRequest(error:String) extends ServiceResponse
implicit val invalidRequestFormat = jsonFormat1(InvalidRequest)
당신은 당신의 라우팅 트리에서 새 service
방법을 사용할 수 있습니다 다음과 같이
val routes:Route = {
path("api"/"foo"){
get{
service[Foo](fooActor, FooActor.DoFoo)
}
}
}
귀하의 예제와 문제 응답을 작성하기 전에 Future
완료를 기다리지 않았습니까? 실행시 지우기로 제거되는 Future
의 기본 유형과 일치 시키려고 했으므로 그런 식으로 시도하고 비교하는 것은 좋지 않습니다. 대신 완료 될 때까지 기다렸다가 Future
뒤에있는 유형을 확인해야합니다.
json에 대한 마셜링에 Akka의 스프레이 json 지원을 사용하고 있습니까? – cmbaxter
예 질문을 업데이트했습니다. – Randomize
http 상태를 408로 변경하는 것이 더 쉬울 수도 있다고 생각합니다. – Randomize