Scala 将HTTP/REST请求转发到Spray中的另一个REST服务器

Scala 将HTTP/REST请求转发到Spray中的另一个REST服务器,scala,rest,http,akka,spray,Scala,Rest,Http,Akka,Spray,我有一组现有的REST服务(下面的1和2)运行在不同的端点上,这些端点只在内部使用。现在我想使用Spray对外公开一些RESTAPI(API-1和API-2),因为这个外部端点还将提供一些额外的API(API-3、API-4) 是否有一种简单/推荐的方法将外部REST请求转发到我的新端点到现有的REST端点 听起来您想要的是建议的proxyTo指令: path("foo") { get { proxyTo("http://oldapi.example.com") } } (或者

我有一组现有的REST服务(下面的1和2)运行在不同的端点上,这些端点只在内部使用。现在我想使用Spray对外公开一些RESTAPI(API-1和API-2),因为这个外部端点还将提供一些额外的API(API-3、API-4)

是否有一种简单/推荐的方法将外部REST请求转发到我的新端点到现有的REST端点


听起来您想要的是建议的
proxyTo
指令:

path("foo") {
  get {
    proxyTo("http://oldapi.example.com")
  }
}
(或者更可能的是,
proxytounmachedpath
)。有一个问题有待解决:

看起来有人在做这件事;下面是一个Spray fork中的提交:

但提交似乎还没有出现在主喷雾回购中。您可以在问题页面上询问其状态

此外,这里是CakeSolutions的一篇博客文章,介绍如何手动执行代理:

该页面上的一条评论指出Spray有一个名为
ProxySettings
的未经记录的东西,并指出了它的以下测试:

更新;Soumya在Spray用户Google Group上向Spray团队询问了这一点:

我能够在代理服务器的帮助下代理单个服务。在下面的示例中,代理正在
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)
}
}

}


我不是100%理解这个问题——但是如果你只是想要简单的转发,为什么不把Apache或一些Web服务器放在前面,让它通过proxypass来实现呢?反向代理/负载平衡器在路由流量方面可能比spray服务器做得更好。如果我只想路由,我本可以做到这一点。但是,我需要在新的REST服务中提供一些额外的API(API-3、API-4),并包装对现有API(API-1、API-2)的调用。您仍然可以使用类似nginx/apache的东西来支持您的场景,而不必在scala代码中进行代理。您可以在webserver配置中设置规则,以仅支持代理某些URL(API1和API2),然后将其余URL(3和4)分配给底层的spray服务器。我们用nginx做这件事。@cmbaxter-这很有帮助。如果可能的话,你能告诉我一些地方开始使用nginx配置吗。应该作为一个起点。
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)
}