2016-07-12 5 views
2

는 내가 다시 특정 메시지가 나는 같은 오류 메시지 등의 내용 포장 할 :Akka : 메시지 내용을 HTTP 응답으로 래핑하는 방법은 무엇입니까? 내 Akka - HTTP 경로에서

val response:Future[T] = (actor ? command).mapTo[T] 
    response match { 
     case err : Future[InvalidRequest] => 
      HttpResponse(408, entity = err.map(_.toJson).????) 
     case r : Future[T] => r.map(_.toJson) 
    } 

case class InvalidRequest(error:String) 

implicit val invalidRequestFormat = jsonFormat1(InvalidRequest) 

을하지만 작동하지 않습니다. json 형식의 텍스트로 어떻게 매핑 할 수 있습니까?

+0

json에 대한 마셜링에 Akka의 스프레이 json 지원을 사용하고 있습니까? – cmbaxter

+0

예 질문을 업데이트했습니다. – Randomize

+0

http 상태를 408로 변경하는 것이 더 쉬울 수도 있다고 생각합니다. – Randomize

답변

2

나는 당신이하려고하는 것에 대한 일반적인 해결책을 제공 할 수 있다고 생각합니다. 당신은 다음과 같이 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 뒤에있는 유형을 확인해야합니다.

+0

감사합니다. 나는 Akka 2.4.7을 사용하고 있으며'complete '에 대한 유일하게 유효한 서명은'def complete (m : ⇒ ToResponseMarshallable)'이므로 상태를 주입 할 수 없다. – Randomize

+0

@Randomize, 기회가 있으면 Akka 2.4.8까지 올릴 수 있습니까? – cmbaxter

+0

네, 해냈습니다. 그러나 그냥 이렇게했다 :'complete (StatusCodes.BadRequest, ir.error)' – Randomize

관련 문제