Распылите ввод-вывод, добавьте заголовок в ответ

У меня есть (ранее) веб-сервис REST spray.io. Теперь мне нужно сгенерировать SESSIONID в одном из моих методов, чтобы использовать его с некоторыми другими методами. И я хочу, чтобы это было в заголовке ответа.

В принципе, я представляю себе логику следующим образом:

 path("/...") {
   get {
     complete {
       // some logic here
       // .....
       someResult match {
         case Some(something) =>
           val sessionID = generateSessionID
           session(sessionID) = attachSomeData(something)
           // here I need help how to do my imaginary respond with header
           [ respond-with-header ? ]("X-My-SessionId", sessionID) {
             someDataMarshalledToJSON(something)
           }


         case None => throw .... // wrapped using error handler
       }
     } 
   }
 }

Но это не работает внутри полной, я имею в виду директиву respondWithHeader. Мне нужен совет.


person dmitry    schedule 28.07.2014    source источник


Ответы (1)


В Spray есть директива respondWithHeader. Вот официальный документ и пример того, как вы можете его использовать:

 def respondWithSessionId(sessionID: String) =
   respondWithHeader(RawHeader("X-My-SessionId", sessionID))

 path("/...") {
   get {
       // some logic here
       // .....
       sessionIDProvider { sessionID =>
           respondWithMediaType(`application/json`) { // optionally add this if you want
             respondWithSessionId(sessionID) {
               complete(someDataMarshalledToJSON(something))
             }
           }
       }
   }
 }
person yǝsʞǝla    schedule 28.07.2014
comment
Они говорят, что код вне завершения будет оцениваться во время построения маршрута, не принесет ли это здесь нежелательных эффектов? Также у меня есть некоторые директивы validate() и params() в настоящее время до complete. - person dmitry; 28.07.2014
comment
Да все верно, просто мне было лень все переносить в complete. Просто оберните вещи такими директивами, как: params { validate { ... } }. Я предпочитаю не включать все эти переменные в маршрут и вместо этого вызывать какую-нибудь функцию, чтобы маршрут был очень простым и понятным. - person yǝsʞǝla; 28.07.2014
comment
Спасибо, я нашел более простое решение для моего конкретного случая: provide(generateSessionId) { sessionId => respondWithHeader(.., sessionId) { complete and the rest unchanged, can use sessionId inside } } . - person dmitry; 28.07.2014
comment
Не могли бы вы обновить ответ правильным решением? Мне нужно добавить заголовок Raw/Custom самостоятельно, и я немного не понимаю, как это сделать. - person djsumdog; 21.10.2016
comment
@djsumdog просто используйте respondWithHeader(RawHeader("your_header_name", header_value)) { ... your code that completes the route ... }, как показано в ответе. Например: respondWithHeader(RawHeader("MYHEADER", "123")) { complete("test") } - person yǝsʞǝla; 22.10.2016