如何在 scala akka-http 中定义通用路由
How can I define generic routing in scala akka-http
我想在 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)
这样我就可以重用重复的代码。我怎样才能实现定义的通用路由?
您可以使用函数组合提取 authenticateOAuth2Async
、path
和 pathEndOrSingleSlash
指令。您可以编写将提供 "common" 框架的高阶函数,然后调用提供特定功能的函数:
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)
}
我想在 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)
这样我就可以重用重复的代码。我怎样才能实现定义的通用路由?
您可以使用函数组合提取 authenticateOAuth2Async
、path
和 pathEndOrSingleSlash
指令。您可以编写将提供 "common" 框架的高阶函数,然后调用提供特定功能的函数:
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)
}