将 HTTP/REST 请求转发到 Spray 中的另一个 REST 服务器
Forwarding HTTP/REST Request to another REST server in Spray
我有一堆现有的 REST 服务(下面的#1 和#2),它们 运行 在不同的端点上,仅供内部使用。现在我想使用 Spray 在外部公开其中一些 REST APIs(API-1 和 API-2),因为这个外部端点还将提供一些额外的 APIs (API-3,API-4)。
是否有 simple/recommended 方法将外部 REST 请求转发到我的新端点到现有的 REST 端点?
听起来你想要的是提议的 proxyTo
指令:
path("foo") {
get {
proxyTo("http://oldapi.example.com")
}
}
(或者更可能是 proxyToUnmatchedPath
)。有一个未解决的问题:
https://github.com/spray/spray/issues/145
看起来有人在做这件事;这是 Spray fork 中的提交:
https://github.com/bthuillier/spray/commit/d31fc1b5e1415e1b908fe7d1f01f364a727e2593
但是提交似乎还没有出现在 Spray 主仓库中。你可以在问题页面上询问它的状态。
此外,这里有一篇来自 CakeSolutions 的博客 post,介绍如何手动执行代理:
http://www.cakesolutions.net/teamblogs/http-proxy-with-spray
该页面上的评论指出 Spray 有一个名为 ProxySettings
的未记录的东西,并指出对其进行以下测试:
更新; Soumya 已经在 spray-user Google 群组上询问了 Spray 团队:
https://groups.google.com/forum/#!topic/spray-user/MlUn-y4X8RE
在 CakeSolution blog 的帮助下,我能够代理 单个 服务。在以下示例中,代理是 http://localhost:20000
上的 运行,实际 REST 端点是 http://localhost:7001
上的 运行。
不确定如何使用这种方法代理多个服务。
我喜欢@cmbaxter 使用 Nginx 作为代理的解决方案,但我仍然很好奇是否有办法扩展以下方法以在 Spray 中执行此操作。
import akka.actor.{ActorRef, Props}
import akka.io.IO
import akka.util.Timeout
import spray.can.Http
import spray.can.Http.ClientConnectionType
import spray.http.HttpResponse
import spray.routing.{RequestContext, HttpServiceActor, Route}
import scala.concurrent.duration._
import akka.pattern.ask
object ProxyRESTService {
def main(args: Array[String]) {
//create an actor system
implicit val actorSystem = akka.actor.ActorSystem("proxy-actor-system")
implicit val timeout: Timeout = Timeout(5 seconds)
implicit val dis = actorSystem.dispatcher
//host on which proxy is running
val proxyHost = "localhost"
//port on which proxy is listening
val proxyPort = 20000
//host where REST service is running
val restServiceHost = "localhost"
//port where REST service is running
val restServicePort = 7001
val setup = Http.HostConnectorSetup(
proxyHost,
proxyPort,
connectionType = ClientConnectionType.Proxied(restServiceHost, restServicePort)
)
IO(Http)(actorSystem).ask(setup).map {
case Http.HostConnectorInfo(connector, _) =>
val service = actorSystem.actorOf(Props(new ProxyService(connector)))
IO(Http) ! Http.Bind(service, proxyHost, port = proxyPort)
}
}
}
.
class ProxyService(connector: ActorRef) extends HttpServiceActor {
implicit val timeout: Timeout = Timeout(5 seconds)
implicit def executionContext = actorRefFactory.dispatcher
val route: Route = (ctx: RequestContext) => ctx.complete(connector.ask(ctx.request).mapTo[HttpResponse])
def receive: Receive = runRoute(route)
}
我有一堆现有的 REST 服务(下面的#1 和#2),它们 运行 在不同的端点上,仅供内部使用。现在我想使用 Spray 在外部公开其中一些 REST APIs(API-1 和 API-2),因为这个外部端点还将提供一些额外的 APIs (API-3,API-4)。
是否有 simple/recommended 方法将外部 REST 请求转发到我的新端点到现有的 REST 端点?
听起来你想要的是提议的 proxyTo
指令:
path("foo") {
get {
proxyTo("http://oldapi.example.com")
}
}
(或者更可能是 proxyToUnmatchedPath
)。有一个未解决的问题:
https://github.com/spray/spray/issues/145
看起来有人在做这件事;这是 Spray fork 中的提交:
https://github.com/bthuillier/spray/commit/d31fc1b5e1415e1b908fe7d1f01f364a727e2593
但是提交似乎还没有出现在 Spray 主仓库中。你可以在问题页面上询问它的状态。
此外,这里有一篇来自 CakeSolutions 的博客 post,介绍如何手动执行代理:
http://www.cakesolutions.net/teamblogs/http-proxy-with-spray
该页面上的评论指出 Spray 有一个名为 ProxySettings
的未记录的东西,并指出对其进行以下测试:
更新; Soumya 已经在 spray-user Google 群组上询问了 Spray 团队:
https://groups.google.com/forum/#!topic/spray-user/MlUn-y4X8RE
在 CakeSolution blog 的帮助下,我能够代理 单个 服务。在以下示例中,代理是 http://localhost:20000
上的 运行,实际 REST 端点是 http://localhost:7001
上的 运行。
不确定如何使用这种方法代理多个服务。
我喜欢@cmbaxter 使用 Nginx 作为代理的解决方案,但我仍然很好奇是否有办法扩展以下方法以在 Spray 中执行此操作。
import akka.actor.{ActorRef, Props}
import akka.io.IO
import akka.util.Timeout
import spray.can.Http
import spray.can.Http.ClientConnectionType
import spray.http.HttpResponse
import spray.routing.{RequestContext, HttpServiceActor, Route}
import scala.concurrent.duration._
import akka.pattern.ask
object ProxyRESTService {
def main(args: Array[String]) {
//create an actor system
implicit val actorSystem = akka.actor.ActorSystem("proxy-actor-system")
implicit val timeout: Timeout = Timeout(5 seconds)
implicit val dis = actorSystem.dispatcher
//host on which proxy is running
val proxyHost = "localhost"
//port on which proxy is listening
val proxyPort = 20000
//host where REST service is running
val restServiceHost = "localhost"
//port where REST service is running
val restServicePort = 7001
val setup = Http.HostConnectorSetup(
proxyHost,
proxyPort,
connectionType = ClientConnectionType.Proxied(restServiceHost, restServicePort)
)
IO(Http)(actorSystem).ask(setup).map {
case Http.HostConnectorInfo(connector, _) =>
val service = actorSystem.actorOf(Props(new ProxyService(connector)))
IO(Http) ! Http.Bind(service, proxyHost, port = proxyPort)
}
}
}
.
class ProxyService(connector: ActorRef) extends HttpServiceActor {
implicit val timeout: Timeout = Timeout(5 seconds)
implicit def executionContext = actorRefFactory.dispatcher
val route: Route = (ctx: RequestContext) => ctx.complete(connector.ask(ctx.request).mapTo[HttpResponse])
def receive: Receive = runRoute(route)
}