Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Playframework接受版本路由_Playframework_Playframework 2.2 - Fatal编程技术网

Playframework接受版本路由

Playframework接受版本路由,playframework,playframework-2.2,Playframework,Playframework 2.2,我试图在Play2.2中实现REST版本控制 我希望客户端在标题中发送以下内容: Accept: application/vnd.helloworld+json; version=1 并且基于该版本头,服务器将调用匹配的控制器操作。我计划为每个api版本快照一个完整的控制器包 大概是这样的: com.helloworld.v1.controllers com.helloworld.v2.controllers 例如: POST /users/login { "email": "foo@gma

我试图在Play2.2中实现REST版本控制

我希望客户端在标题中发送以下内容:

Accept: application/vnd.helloworld+json; version=1
并且基于该版本头,服务器将调用匹配的控制器操作。我计划为每个api版本快照一个完整的控制器包

大概是这样的:

com.helloworld.v1.controllers
com.helloworld.v2.controllers
例如:

POST /users/login
{ "email": "foo@gmail.com", "password": "bar" }
我想将该请求发送给以下控制员:

com.helloworld.v1.controllers.UserController

如何在Global.onRouterRequest中干净利落地实现这一点

在考虑了一会儿之后,我很难想象这是如何按照您描述的方式工作的,而不使用运行时反射按版本调用包/类。我也会厌倦这样做,因为你说你的API版本可能有不同的参数,这会使类型不兼容

下面是一种方法,通过在路由中定义默认的API URI,然后为每个版本定义一个URI。在
onroutereRequest
中,您可以将传入的请求重新路由到不同的URI(无需使用
重定向
),并且用户仍然不知道这些URI是否存在。请注意,需要查询参数来允许它们通过默认url(如果类型要更改,我认为没有其他方法)

路线:

GET     /api                        controllers.Application.index
GET     /v1/api                     controllers.v1.Test.index(test: Int ?= 0)
GET     /v2/api                     controllers.v2.Test.index(test: String ?= "")
GlobalSettings
对象中:

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

我认为不清洁的唯一部分是列举路线的必要性,考虑到反向路由编译器通常所做的代码体操,这将是很难克服的。

考虑了一段时间后,我很难想象这会以您描述的方式工作,而不使用运行时反射按版本调用包/类。我也会厌倦这样做,因为你说你的API版本可能有不同的参数,这会使类型不兼容

下面是一种方法,通过在路由中定义默认的API URI,然后为每个版本定义一个URI。在
onroutereRequest
中,您可以将传入的请求重新路由到不同的URI(无需使用
重定向
),并且用户仍然不知道这些URI是否存在。请注意,需要查询参数来允许它们通过默认url(如果类型要更改,我认为没有其他方法)

路线:

GET     /api                        controllers.Application.index
GET     /v1/api                     controllers.v1.Test.index(test: Int ?= 0)
GET     /v2/api                     controllers.v2.Test.index(test: String ?= "")
GlobalSettings
对象中:

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

唯一的一部分,我认为不干净是必要的枚举路线,这将是难以克服的代码体操反向路线编译器通常做。< / P> URL是容易互换的?可能有额外的路线在后续版本的API,api在不同版本之间可能有不同的参数。我的意思是,就像regex在请求URI中为

v2
替换
v1
一样。从客户端的角度来看,不会有v1或v2。我们试图实现这个规范:URL容易互换吗?在api的后续版本中可能会有额外的路由,api在不同版本之间可能有不同的参数。我的意思是,就像regex在请求URI中为
v2
替换
v1
一样。从客户端的角度来看,不会有v1或v2。我们正在尝试实现这个规范:我同意,这可能是最好的方法。枚举版本路由并不会让我太烦恼,可能会分割路由并在主路由文件中导入带有前缀的每个版本路由。此解决方案保留了反向路由器所做的所有工作nice@JamesCowhen“可能拆分路由并在主路由文件中导入带有前缀的每个版本路由”-如何完成?我也面临同样的问题。我同意,这可能是最好的办法。枚举版本路由并不会让我太烦恼,可能会分割路由并在主路由文件中导入带有前缀的每个版本路由。此解决方案保留了反向路由器所做的所有工作nice@JamesCowhen“可能拆分路由并在主路由文件中导入带有前缀的每个版本路由”-如何完成?我也面临同样的问题。