2014-06-20 2 views
0

Play 2.2에서 REST 버전 관리를 구현하려고합니다.Playframework 버전 라우팅 수락

Accept: application/vnd.helloworld+json; version=1 

그리고 그 버전 헤더를 기반으로, 서버가 일치하는 컨트롤러 액션을 호출합니다 :

나는 클라이언트가 헤더에 다음을 보낼 것으로 기대합니다. 각 버전의 API에 대한 완벽한 컨트롤러 패키지를 스냅 샷으로 만들 계획입니다. 이 같은

뭔가 : 예를 들어

com.helloworld.v1.controllers 
com.helloworld.v2.controllers 

:

POST /users/login 
{ "email": "[email protected]", "password": "bar" } 

나는 다음과 같은 컨트롤러에 해당 요청 직접 싶습니다 :

com.helloworld.v1.controllers.UserController 

을 어떻게 내가 깨끗하게 그것을 달성하십시오 Glob al.onRouteRequest?

+0

URL은 쉽게 바꿔 쓸 수 있습니까? –

+0

다음 버전의 API에는 추가 경로가있을 수 있으며 api는 버전간에 서로 다른 매개 변수를 가질 수 있습니다. –

+0

요청 URI에서'v2'를'v1'로 대체하는 정규식과 같은 의미입니다. –

답변

4

잠시 생각한 후 런타임 리플렉션을 사용하지 않고도 버전별로 패키지/클래스를 호출하지 않고도 이러한 방식으로 작업하는 것을 상상하기가 힘듭니다. 또한 API 버전에 매개 변수가 다를 수 있으므로 형식이 호환되지 않을 수 있다고 말한 것처럼 그렇게하는 것이 지칠 것입니다.

경로에 기본 API URI를 정의한 다음 각 버전에 대한 URI를 정의하여이를 수행 할 수 있습니다. onRouteRequest에서 들어오는 요청을 다른 URI (Redirect을 사용하지 않고)로 다시 라우팅 할 수 있으며 다른 URI가 사용자에게 알려지지 않은 채로 남아 있습니다. 쿼리 매개 변수는 기본 URL을 통과 할 수 있도록해야합니다 (유형이 변경 될 경우 다른 방법이 있다고 생각하지 않습니다).

경로 :

GlobalSettings 객체에서
GET  /api      controllers.Application.index 
GET  /v1/api      controllers.v1.Test.index(test: Int ?= 0) 
GET  /v2/api      controllers.v2.Test.index(test: String ?= "") 

:

override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    // Strip the version from the headers 
    val regex = "version=(\\d+)".r 
    val version: Option[Int] = request.headers.get("Accept").flatMap(x => regex.findFirstMatchIn(x).map(_.group(1).toInt)) 

    // Copy the version to the URI (if found) in a new RequestHeader (if found), and re-route 
    val req: RequestHeader = version.map(v => 
     request.copy(
      uri = "/v" + v.toString + request.uri, 
      path = "/v" + v.toString + request.path 
     ) 
    ).getOrElse(request) 

    super.onRouteRequest(req) 
} 

내가 부정한 생각이 솔루션의 유일한 부분은 코드를 고려 극복하기 어려울 것이다 열거 루트의 필요성이다 컴파일러가 일반적으로하는 역방향 경로.

+0

동의합니다. 아마도 이것이 최선의 방법 일 것입니다. 버전 경로를 열거해도별로 신경 쓰지 않고, 경로를 분할하고 기본 경로 파일의 접두사가있는 각 버전 경로를 가져올 수 있습니다. 이 솔루션은 역방향 라우터가 수행하는 모든 작업을 보존합니다. –

+0

@JamesCowhen "경로를 분할하고 주 경로 파일의 접두사가있는 각 버전 경로를 가져올 수 있습니다"- 어떻게 처리 될까요? 나는 똑같은 문제에 직면 해있다. – Sofia