Playframework Accept version routing -
i trying implement rest versioning in play 2.2.
i expect client send next in header:
accept: application/vnd.helloworld+json; version=1
and based on version header, server phone call matching controller action. plan snapshot finish controller bundle each version of api.
something this:
com.helloworld.v1.controllers com.helloworld.v2.controllers
for example:
post /users/login { "email": "foo@gmail.com", "password": "bar" }
i direct request next controller:
com.helloworld.v1.controllers.usercontroller
how can cleanly accomplish in global.onrouterequest?
after thinking awhile i'm having hard time imagining working way describe without using runtime reflection phone call package/classes version. i'd weary of doing way, api versions may have different parameters, create types incompatible.
here's way defining default api uri in routes, uri each version. in onrouterequest
can re-route incoming request different uri, (without using redirect
) , remain unknown user other uris exist. note query parameters needed allow them pass through default url (if types going changing, don't think there's way).
routes:
get /api controllers.application.index /v1/api controllers.v1.test.index(test: int ?= 0) /v2/api controllers.v2.test.index(test: string ?= "")
in globalsettings
object:
override def onrouterequest(request: requestheader): option[handler] = { // strip version headers val regex = "version=(\\d+)".r val version: option[int] = request.headers.get("accept").flatmap(x => regex.findfirstmatchin(x).map(_.group(1).toint)) // re-create version uri (if found) in new requestheader (if found), , 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) }
the part of solution consider unclean necessity enumerated routes, hard overcome considering code gymnastics reverse routes compiler does.
playframework playframework-2.2
No comments:
Post a Comment