Skip to content

Instantly share code, notes, and snippets.

@doytsujin
Forked from Cowa/reverse-proxy-demo.scala
Created November 3, 2022 00:20
Show Gist options
  • Save doytsujin/59e669706134685e26354bde247345a8 to your computer and use it in GitHub Desktop.
Save doytsujin/59e669706134685e26354bde247345a8 to your computer and use it in GitHub Desktop.
package controllers
import config.{EndpointConfig => Config}
import play.api.mvc._
import play.api.Play.current
import play.api.libs.ws.{WSRequest, WS}
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
object ReverseProxy extends Controller {
/**
* Proxy to poems API
*/
def poems(path: String) = Action.async(parse.raw) { r: Request[RawBuffer] =>
val request = proxifyRequest(Config.poemsEndpoint, r)
streamResponse(request)
}
/**
* Proxy to transactions API
*/
def transactions(path: String) = Action.async(parse.raw) { r: Request[RawBuffer] =>
val request = proxifyRequest(Config.transactionsEndpoint, r)
streamResponse(request)
}
/**
* Proxify a request to an endpoint
*/
private def proxifyRequest(endpoint: String, request: Request[RawBuffer]): WSRequest = {
WS.url(endpoint + request.path)
.withFollowRedirects(false)
.withMethod(request.method)
.withVirtualHost(Config.endpoint)
.withBody(request.body.asBytes().get)
.withHeaders(request.headers.toSimpleMap.toSeq: _*)
.withQueryString(request.queryString.mapValues(_.head).toSeq: _*)
}
/**
* Stream response to user
*/
private def streamResponse(request: WSRequest): Future[Result] = {
request.stream().map {
case (headers, enum) =>
Result(ResponseHeader(headers.status, headers.headers.mapValues(_.head)), enum)
}
}
}
GET / controllers.ReverseProxy.index
# To poems API
GET /poems/*path controllers.ReverseProxy.poems(path: String)
POST /poems/*path controllers.ReverseProxy.poems(path: String)
PUT /poems/*path controllers.ReverseProxy.poems(path: String)
DELETE /poems/*path controllers.ReverseProxy.poems(path: String)
# To transactions API
GET /transactions/*path controllers.ReverseProxy.transactions(path: String)
POST /transactions/*path controllers.ReverseProxy.transactions(path: String)
PUT /transactions/*path controllers.ReverseProxy.transactions(path: String)
DELETE /transactions/*path controllers.ReverseProxy.transactions(path: String)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment