首页 文章

如何以编程方式在Akka Http中调用Route

提问于
浏览
2

在Akka Http中,可以通过这种方式定义路由系统来管理REST基础架构,如下所述:https://doc.akka.io/docs/akka-http/current/routing-dsl/overview.html

val route =
      get {
        pathSingleSlash {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`,"<html><body>Hello world!</body></html>"))
        } ~
          path("ping") {
            complete("PONG!")
          } ~
          path("crash") {
            sys.error("BOOM!")
          }
      }

有没有办法以类似于以下语句的方式以编程方式调用同一应用程序中的一个路由?

val response = (new Invoker(route = route, method = "GET", url = "/ping", body = null)).Invoke()

其中 Response 与服务的远程HTTP调用的结果相同?

前面提到的API只是为了让我知道我的想法,我希望能够设置内容类型, Headers 等 .

2 回答

  • 1

    如果这是用于单元测试,则可以使用akka-http's test kit .

    如果这是应用程序本身,您不应该通过该路由,您应该只调用控制器将直接使用的相关服务 . 如果这很不方便(复制意大利面太多),重构直到变得可能 .

    至于原因,我希望我的应用程序包含在Web服务器(然后使用“正常”方式的路由)和响应消息代理入站消息的守护进程中 .

    我有一个应用程序实际上做了类似的事情 .

    但是我从另一个方面来到这里:我认为代理消息是“主要”格式 . 它完全基于消息本身的属性(正文内容,消息密钥,主题名称)在消费者内部“路由” . HTTP网关 Build 在它之上:它只有非常有限数量的API endpoints 和路由(主要是为了调用方便,也可能只有一个)并构造一条消息然后传递给消息使用者(在我的例子中,实际上是通过代理,因此HTTP网关甚至不必与消费者在同一主机上) .

    因此,我不必“重用”HTTP路由,因为它实际上没有做任何事情 . 所有共享处理逻辑都发生在较低级别(服务内部,消费者内部) .

  • 1

    最后,我设法通过在Akka HTTP文档中挖掘更多内容来找到我自己的问题的答案 .

    如上所述:https://doc.akka.io/docs/akka-http/current/routing-dsl/routes.htmlRoute 是一个定义如下的类型:

    type Route = RequestContext => Future[RouteResult]
    

    其中 RequestContextHttpRequest 的包装器 . 但是也可以将 Route 隐式或非隐式转换为其他函数类型,如下所示:

    def asyncHandler(route: Route)(...): HttpRequest ⇒ Future[HttpResponse]
    

    因此,确实可以通过将路由转换为另一种函数类型,然后简单地传递 HttpRequest 构建ad hoc,接收包含所需响应的Future . 转换比其他操作需要更多的时间,但是这可以在bootrstrapping应用程序时完成 .

    Note :转换需要这些导入,如下所述:https://doc.akka.io/docs/akka-http/current/introduction.html

    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher
    

    但是这些导入对于创建服务本身已经是强制性的 .

相关问题