我想在Scala Akka-HTTP中创建可重用的通用路由,以便我可以为我定义的其余路由使用相同的通用路由。
到目前为止,我可以将路由定义如下,以便完美运行。
class TestApi(val modules: Configuration with PersistenceService)(implicit executionContext: ExecutionContext) extends BaseApi with CirceSupport {
override val oauth2DataHandler = modules.oauth2DataHandler
val userDao = new TestService
val testApi = pathPrefix("auth") {
path("users") {
pathEndOrSingleSlash {
get {
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) {
//auth => complete(userService.getAll().map(_.asJson))
auth => complete(userDao.getAll().map(_.asJson))
}
}
}
} ~
path("allUsers") {
pathEndOrSingleSlash {
post {
entity(as[UserEntity1]) { userUpdate =>
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) {
//auth => complete(userService.getAll().map(_.asJson))
auth => complete(userDao.getAll().map(_.asJson))
}
}
}
}
}
} ~
path("user" / "upload" / "file") {
pathEndOrSingleSlash {
post {
entity(as[Multipart.FormData]) { fileData =>
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) {
auth => {
val fileName = UUID.randomUUID().toString
val temp = System.getProperty("java.io.tmpdir")
val filePath = "/var/www/html" + "/" + fileName
complete (
FileHandler.processFile(filePath,fileData).map { fileSize =>
("success", fileSize)
//HttpResponse(StatusCodes.OK, entity = s"File successfully uploaded. File size is $fileSize")
}.recover {
case ex: Exception => ("error", 0) //HttpResponse(StatusCodes.InternalServerError, entity = "Error in file uploading")
}.map(_.asJson)
)
}
}
}
}
}
}
}
我在代码中找到了pathEndOrSingleSlash
和
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) {
auth => ...
}
但却难免重复。
我想得到类似下面的内容。
get(url, function)
post(url, function)
put(url, function)
这样我就可以重复使用重复代码了。我怎样才能实现定义的通用路由?
答案 0 :(得分:1)
您可以使用功能组合提取authenticateOAuth2Async
,path
和pathEndOrSingleSlash
指令。您可以编写一个更高阶的函数来提供“通用”框架,然后调用一个提供特定功能的函数:
def commonRoute(p : String, subRoute : AuthInfo[OauthAccount] => Route) =
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) { auth =>
path(p) {
pathendOrSingleSlash {
subRoute(auth)
}
}
}
然后可以将其应用于您的特定情况:
//example code doesn't use the auth variable anywhere, thus the "_ =>"
val getRoute : AuthInfo[OauthAccount] => Route =
_ =>
get {
complete(userDao.getAll().map(_.asJson))
}
val postAllUsersRoute : AuthInfo[OauthAccount] => Route =
_ =>
post {
entity(as[UserEntity1]) { userUpdate =>
complete(userDao.getAll().map(_.asJson)
}
}
然后合并形成你的最终Route
:
val testApi = pathPrefix("auth") {
commonRoute("users", getRoute) ~ commonRoute("allUsers", postAllUersRoute)
}