2015-01-17 57 views
9

我有一堆现有的REST服务(下面的#1和#2)运行在仅用于内部的不同端点上。现在我想使用Spray在外部公开部分这些REST API(API-1和API-2),因为此外部端点还将提供一些其他API(API-3,API-4)。转发HTTP/REST请求到喷雾中的另一个REST服务器

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

enter image description here

+2

不是100%我明白这个问题 - 但是如果你只是想简单转发,为什么不把Apache或者一些web服务器放在前面,让它通过proxypass来实现呢?反向代理/负载均衡器在路由喷流服务器的流量时可能会做得更好。 –

+0

如果我只想要路由,我可以做到这一点。但是,我需要在* new * REST服务中提供一些额外的API(API-3,API-4)以及将调用包装到*现有* API(API-1,API-2)。 –

+1

你仍然可以使用像nginx/apache这样的东西来支持你的场景,而无需在scala代码中进行代理。您可以在web服务器配置中设置规则来支持代理某些URL(API 1和API 2),然后让剩下的(3和4)通过您的底层喷雾服务器。我们用nginx做这件事。 – cmbaxter

回答

4

这听起来像你想要的是所提出的proxyTo指令:

path("foo") { 
    get { 
    proxyTo("http://oldapi.example.com") 
    } 
} 

(或者,更可能的是,proxyToUnmatchedPath)。有开放它的一个问题:

https://github.com/spray/spray/issues/145

貌似有人一直致力于此;这里是喷雾叉提交:

https://github.com/bthuillier/spray/commit/d31fc1b5e1415e1b908fe7d1f01f364a727e2593

但承诺似乎还没有要在主喷射回购。您可以询问其在问题页面上的状态。

而且,这里是从CakeSolutions一篇博客文章,你如何能做到手动代理:

http://www.cakesolutions.net/teamblogs/http-proxy-with-spray

在该页面指向一个评论指出,喷雾有一个名为ProxySettings一个未公开的事情,并指出它以下测试:

https://github.com/spray/spray/blob/master/spray-can-tests/src/test/scala/spray/can/client/ProxySpec.scala

UPDATE; Soumya已要求喷雾队这个上喷雾用户谷歌组:

https://groups.google.com/forum/#!topic/spray-user/MlUn-y4X8RE

3

我能代理一个服务与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) 
} 
相关问题