2017-01-05 5 views
0

Я хотел создать многоразовую маршрутизацию в 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 => ... 
} 

repetative.

Я хотел бы получить что-то вроде ниже для работы.

get(url, function) 
post(url, function) 
put(url, function) 

Чтобы повторное использование повторяющегося кода. Как я могу достичь общей маршрутизации, как определено?

ответ

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) 
} 
+0

Спасибо! Он отлично работает. Но он не работает для Path со следующим синтаксисом: «user»/«edit»/IntVal, так как ваш код использует String. Я попытался с PathMatcher0, но опять-таки это может быть не только. – Sujit

+0

Добро пожаловать. Если вам не нужен «IntVal», то как насчет «commonRoute» ((«user»/«edit» /IntVal).toString, ...) '? Если вам нужен IntVal, вам может понадобиться абстрагировать часть пути, аналогичную тому, как я абстрагировал часть аутентификации ... –

+0

Я попробую и дам вам знать – Sujit