Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play2-mini and Akka2 for HTTP gateway

I'm evaluating the possibility of using Play2-mini with Scala to develop a service that will sit between a mobile client and existing web service. I'm looking for the simplest possible example of a piece of code where Play2-mini implements a server and a client. Ideally the client will use Akka2 actors.

With this question, I'm trying to find out how it is done, but also to see how Play2-Mini and Akka2 should co-operate. Since Play2-Mini appears to be the replacement for the Akka HTTP modules.

Play2-mini contains the following code example, in which I created two TODO's. If someone can help me with some sample code to get started, I will be really grateful.

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")
    }
  }
}
like image 866
Jack Avatar asked Feb 13 '12 12:02

Jack


2 Answers

Here's the implementation of your example.

Add the following imports:

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

Add the following route:

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") }
      }
    }

All it does, is forwarding a GET request to a back-end serivce as a POST request. The back-end service is specified in the request parameter as target and the body for the POST request is specified in the request parameter as data (must be valid XML). As a bonus the request is handled asynchronously (hence Async). Once the response from the back-end service is received the front-end service responds with some basic HTML showing the back-end service response.

If you wanted to use request body, I would suggest adding the following POST route rather than GET (again, in this implementation body must be a valid 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") }
      }
    }

So as you can see, for your HTTP Gateway you can use Async and play.api.libs.ws.WS with Akka under the hood working to provide asynchronous handling (no explicit Actors required). Good luck with your Play2/Akka2 project.

like image 128
romusz Avatar answered Nov 03 '22 03:11

romusz


Great answer by romusz

Another way to make a (blocking) HTTP GET request:

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)
like image 35
Tue Avatar answered Nov 03 '22 04:11

Tue