设为首页 加入收藏

TOP

Akka-CQRS(12)- akka-http for http-web-service: Routing-服务项目接口(一)
2019-08-15 00:10:47 】 浏览:110
Tags:Akka-CQRS akka-http for http-web-service: Routing- 服务项目 接口

   上篇提到,按当前对web-service功能需要,我们需要完成数据转换marshalling,服务接口routing这两部分的调研和示范。上篇已经完成了对序列化marshalling的讨论,这篇就介绍一下routing了。akka-http提供了一套功能强大,使用又很方便的Routing DSL。Route是个类型:

type Route = RequestContext ? Future[RouteResult]

实际上就是个把HttpRequest转换成HttpResponse的函数。举个例子: 

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

这个route是个handler Flow, 但Route可以用RouteResult.route2HandlerFlow转换成Flow:

  
/**
   * Turns a `Route` into a server flow.
   *
   * This conversion is also implicitly available through [[RouteResult#route2HandlerFlow]].
   */
  def handlerFlow(route: Route)(implicit
    routingSettings: RoutingSettings,
                                parserSettings:   ParserSettings,
                                materializer:     Materializer,
                                routingLog:       RoutingLog,
                                executionContext: ExecutionContextExecutor = null,
                                rejectionHandler: RejectionHandler         = RejectionHandler.default,
                                exceptionHandler: ExceptionHandler         = null): Flow[HttpRequest, HttpResponse, NotUsed] =
    Flow[HttpRequest].mapAsync(1)(asyncHandler(route))

...

implicit def route2HandlerFlow(route: Route)(
    implicit
    routingSettings:  RoutingSettings,
    parserSettings:   ParserSettings,
    materializer:     Materializer,
    routingLog:       RoutingLog,
    executionContext: ExecutionContext = null,
    rejectionHandler: RejectionHandler = RejectionHandler.default,
    exceptionHandler: ExceptionHandler = null
  ): Flow[HttpRequest, HttpResponse, NotUsed] =
    Route.handlerFlow(route)

route是由Directive类组合而成的一个决策树decision-tree。get、path、pathSingleSlash等都是Directive, 如:

  def path[L](pm: PathMatcher[L]): Directive[L] = pathPrefix(pm ~ PathEnd)

然后complete返回Route类:

  def complete(m: ? ToResponseMarshallable): StandardRoute = StandardRoute(_.complete(m)) ... abstract class StandardRoute extends Route { def toDirective[L: Tuple]: Directive[L] = StandardRoute.toDirective(this) }

Directive的主要功能就是对HttpRequest的Uri进行解析,找出具体的服务接口点,已经对entity里的数据进行调取。

Route是一种可组合组件。我们可以用简单的Route组合成更多层次的Route。下面是组合Route的几种方式:

1、Route转化:对输入的request,输出的response进行转化处理后把实际运算托付给下一层内部(inner)Route

2、筛选Route:只容许符合某种条件的Route通过并拒绝其它不符合条件的Route

3、链接Route:假如一个Route被拒绝,尝试下一个Route。这个是通过 ~ 操作符号实现的

在Akka-http的routing DSL里这些Route组合操作是通过Directive实现的。Akka-http提供了大量现成的Directive,我们也可以自定义一些特殊功能的Directive,详情可以查询官方文件或者api文件。

Directive的表达形式如下: 

dirname(arguments) { extractions => ... // 内层inner route
}

下面是Directive的一些用例: 

下面的三个route效果相等:

val route: Route = { ctx =>
  if (ctx.request.method == HttpMethods.GET) ctx.complete("Received GET") else ctx.complete("Received something else") } val route =
  get { complete("Received GET") } ~ complete("Received something else") val route =
  get { ctx => ctx.complete("Received GET") } ~ complete("Received something else")

下面列出一些Directive的组合例子:

val route: Route = path("order" / IntNumber) { id =>
    get { complete { "Received GET request for order " + id } } ~ put { complete { "R
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Akka-CQRS(11)- akka-http for .. 下一篇play framework + sbt入门之环境..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目