Play!Framework中的批量HTTP请求

我实现了当前的一组路由(例如):

GET /api/:version/:entity my.controllers.~~~~~ GET /api/:version/:entity/:id my.controllers.~~~~~ POST /api/:version/:entity my.controllers.~~~~~ POST /api/:version/:entity/:id my.controllers.~~~~~ DELETE /api/:version/:entity my.controllers.~~~~~ POST /api/:version/search/:entity my.controllers.~~~~~ 

而且他们工作得很漂亮。 现在让我们说我想为同一个API实现“批处理终结点”。 它应该看起来像这样:

 POST /api/:version/batch my.controllers.~~~~~ 

身体应该是这样的:

 [ { "method": "POST", "call": "/api/1/customer", "body": { "name": "antonio", "email": "tonysmallhands@gmail.com" } }, { "method": "POST", "call": "/api/1/customer/2", "body": { "name": "mario" } }, { "method": "GET", "call": "/api/1/company" }, { "method": "DELETE", "call": "/api/1/company/22" } ] 

为此,我想知道如何调用播放框架路由器来传递这些请求? 我打算使用与unit testing建议类似的东西:

 @Test public void badRoute() { Result result = play.test.Helpers.routeAndCall(fakeRequest(GET, "/xx/Kiki")); assertThat(result).isNull(); } 

通过进入routeAndCall()的源代码,你会发现这样的事情:

  /** * Use the Router to determine the Action to call for this request and executes it. * @deprecated * @see #route instead */ @SuppressWarnings(value = "unchecked") public static Result routeAndCall(FakeRequest fakeRequest) { try { return routeAndCall((Class)FakeRequest.class.getClassLoader().loadClass("Routes"), fakeRequest); } catch(RuntimeException e) { throw e; } catch(Throwable t) { throw new RuntimeException(t); } } /** * Use the Router to determine the Action to call for this request and executes it. * @deprecated * @see #route instead */ public static Result routeAndCall(Class router, FakeRequest fakeRequest) { try { play.core.Router.Routes routes = (play.core.Router.Routes)router.getClassLoader().loadClass(router.getName() + "$").getDeclaredField("MODULE$").get(null); if(routes.routes().isDefinedAt(fakeRequest.getWrappedRequest())) { return invokeHandler(routes.routes().apply(fakeRequest.getWrappedRequest()), fakeRequest); } else { return null; } } catch(RuntimeException e) { throw e; } catch(Throwable t) { throw new RuntimeException(t); } } 

所以我的问题是:使用Play(我不是反对混合使用Scala和Java来实现它)是否有一种不那么“hacky”的方式而不是复制上面的代码? 我还想提供并行或按顺序执行批处理调用的选项…我想使用类加载器只实例化一个Routes会有问题吗?

您可以使用以下方法调用来路由您的虚假请求: Play.current.global.onRouteRequest 。 请参阅此post以获取完整示例:http: //yefremov.net/blog/play-batch-api/

您可以使用WS API ,但我个人只是创建一个私有方法来收集数据并从“单一”和“批量”操作中使用它们 – 它肯定会更快。