2015-06-15 1 views
0

я использую спрей-маршрутизацию с Акки, чтобы определить маршрут, какКак установить код статуса и заголовки в распылительных маршрутизациях на основе будущего результата

def items = path("items") { 
    get { 
    complete { 
     actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]] map { 
     result => result match { 
      case Left(_) => StatusCodes.NotModified 
      case Right(items) => 
       // here I want to set an HTTP Response header based on a 
       // field within items -- items.revision 
       items 
     } 
     } 
    } 
    } 
} 

actor.ask возвращает будущее, который получает переведенное в будущее [Либо [NoChange, Items]]. «complete» рад иметь дело с Future [StatusCodes ...] или Future [Items], но я не уверен, как настроить заголовок HTTP-ответа в будущем.

Если заголовок не был установлен в будущем, я мог бы просто обернуть его в директиве, но как установить заголовок в пределах полного?

Я использую Spray 1.2.0.

Спасибо за любые указатели в правильном направлении!

ответ

2

Если вы пытаетесь сделать это внутри complete, все ветви выражения внутри должны приводить к типу, который может быть отсортирован по complete.

Вы можете попробовать структуру, как это сделать его работу:

complete { 
    actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]] map { 
    result => result match { 
     case Left(_) => StatusCodes.NotModified: ToResponseMarshallable 
     case Right(items) => 
      // here I want to set an HTTP Response header based on a 
      // field within items -- items.revision 

      val headers = // items... 
      HttpResponse(..., headers = headers): ToResponseMarshallable 
    } 
    } 
} 

Это гарантирует, что тип выражения вы передаете complete является Future[ToResponseMarshallable], который всегда должен быть marshallable.

Лучший способ, однако, заключается в использовании onSuccess directive, что позволяет использовать другие директивы после того, как будущее было завершено:

get { 
    def getResult() = actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]] 
    onSuccess(getResult()) { 
    case Left(_) => complete(StatusCodes.NotModified) 
    case Right(items) => 
     // do whatever you want, e.g. 
     val extraHeaders = // items.revisions 
     respondWithHeaders(extraHeaders) { 
     complete(...) 
     } 
    } 
} 
+0

Большое спасибо, jrudolph, для решения и указатель на документы на FutureDirectives, идеальная подгонка – jmcnulty