喷涂中的布线设计

1 rest routing scala spray

我正在尝试为个人资料管理提供休息服务.所以我有以下uri的配置文件:

host/profile/id123123/:action
Run Code Online (Sandbox Code Playgroud)

但是对于具有不同仪表板的不同用户,存在不同的配置文件类型,因此我想提取profileTypeid作为顶部路径并在此下使用不同的操作.我试着用DRY方式写它:

path(Segment / "id" ~ Segment) { (profileType, id) ?
  get {
    profileType match {
      case "admin" ? loadProfilePage[Admin](id)
    }
  } ~
  path("update") {
    complete("Profile updated")
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在地址栏中键入以下内容:

localhost/admin/id123123/update
Run Code Online (Sandbox Code Playgroud)

它抛出服务器异常.有什么问题?

4le*_*x1v 6

您的路由结构错误.如果你想在一些常见的路径下为不同的路径设置不同的逻辑path(Segment / "id" ~ Segment),那么你需要使用pathPrefix指令.然后正确的路线将如下所示:

pathPrefix(Segment / "id" ~ Segment) { (profileType, id) ?
  path("") {
    get {
      profileType match {
        case "admin" ? loadProfilePage[Admin](id)
      }
    }
  } ~
  path("update") {
    complete("Profile updated")
  }
}
Run Code Online (Sandbox Code Playgroud)

但仍然提前提取并不是一件好事,如果你有一个非常复杂的路线结构,这将减慢整体性能,而不是很多,但你的内部路线,在提取点后,将动态评估.

更新

我只是稍微优化一下.我认为你不仅要有update其他路径.因此,在这种情况下,制定以下路线会更清晰:

pathPrefix(Segment / "id" ~ Segment) { (profileType, id) ?
  (get | put) {
    profileType match {
      case "user" ?
        path("")(loadProfilePage[User](id)) ~
        path("update")(updateProfile[User](id)) ~
        path("delete")(deleteProfile[User](id)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这仍然不是一个完美的方式,我会进一步概括,导致唯一的事情,据我所知,将改变是 profileType