Play2-mini и Akka2 для HTTP-шлюза - PullRequest
       15

Play2-mini и Akka2 для HTTP-шлюза

8 голосов
/ 13 февраля 2012

Я оцениваю возможность использования Play2-mini с Scala для разработки сервиса, который будет находиться между мобильным клиентом и существующим веб-сервисом.Я ищу самый простой пример кода, где Play2-mini реализует сервер и клиент.В идеале клиент будет использовать актеров Akka2.

С этим вопросом я пытаюсь выяснить, как это делается, а также посмотреть, как Play2-Mini и Akka2 должны сотрудничать.Поскольку Play2-Mini является заменой для модулей Akka HTTP.

Play2-mini содержит следующий пример кода, в котором я создал два TODO.Если кто-то может помочь мне с примером кода, чтобы начать, я буду очень благодарен.

package com.example

import com.typesafe.play.mini._
import play.api.mvc._
import play.api.mvc.Results._

object App extends Application {
  def route = {
    case GET(Path("/testservice")) & QueryString(qs) => Action{ request=>
      println(request.body)
      //TODO Take parameter and content from the request them pass it to the back-end server
      //TODO Receive a response from the back-end server and pass it back as a response
      Ok(<h1>Server response: String {result}</h1>).as("text/html")
    }
  }
}

Ответы [ 2 ]

7 голосов
/ 13 марта 2012

Вот реализация вашего примера.

Добавьте следующий импорт:

import play.api.libs.ws.WS
import play.api.mvc.BodyParsers.parse
import scala.xml.XML

Добавьте следующий маршрут:

case GET(Path("/testservice")) & QueryString(qs) => Action{ request =>
    Async {
      val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
      val tokenData = QueryString(qs,"data") map (_.get(0)) getOrElse("<auth>john</auth>")
      WS.url(backendUrl).post(XML loadString tokenData).map { response =>
      Ok(<html><h1>Posted to {backendUrl}</h1>
         <body>
           <div><p><b>Request body:</b></p>{tokenData}</div>
           <div><p><b>Response body:</b></p>{response.body}</div>
         </body></html>).as("text/html") }
      }
    }

Все, что он делает, это пересылкаGET запрос к серверному серверу как POST запрос.Внутренняя служба указывается в параметре запроса как target, а тело запроса POST указывается в параметре запроса как data (должен быть допустимым XML).В качестве бонуса запрос обрабатывается асинхронно (отсюда Async).Как только ответ от серверной службы получен, интерфейсная служба отвечает некоторым базовым HTML, показывающим ответ серверной службы.

Если вы хотите использовать тело запроса, я бы предложил добавить следующее POST route вместо GET (опять же, в этом теле реализации должен быть действительный XML):

case POST(Path("/testservice")) & QueryString(qs) => Action(parse.tolerantXml){ request =>
    Async {
      val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
      WS.url(backendUrl).post(request.body).map { response =>
      Ok(<html><h1>Posted to {backendUrl}</h1>
         <body>
           <div><p><b>Request body:</b></p>{request.body}</div>
           <div><p><b>Response body:</b></p>{response.body}</div>
         </body></html>).as("text/html") }
      }
    }

Итак, как вы можете видеть, для своего HTTP-шлюза вы можете использовать Async и play.api.libs.ws.WS с Akka под капотом, работающим для обеспечения асинхронной обработки (явные актеры не требуются).Удачи в вашем проекте Play2 / Akka2.

1 голос
/ 22 марта 2012

Отличный ответ от romusz

Другой способ сделать (блокирующий) HTTP-запрос GET:

import play.api.libs.ws.WS.WSRequestHolder  
import play.api.libs.ws.WS.url  
import play.api.libs.concurrent.Promise  
import play.api.libs.ws.Response

val wsRequestHolder: WSRequestHolder = url("http://yourservice.com")  
val promiseResponse: Promise[Response] = wsRequestHolder.get()  
val response = promiseResponse.await.get

println("HTTP status code: " + response.status)
println("HTTP body: " + response.body)
...