У меня есть текущий набор реализованных маршрутов (например):
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": "[email protected]"
}
},
{
"method": "POST",
"call": "/api/1/customer/2",
"body": {
"name": "mario"
}
},
{
"method": "GET",
"call": "/api/1/company"
},
{
"method": "DELETE",
"call": "/api/1/company/22"
}
]
Для этого я хотел бы знать, как я могу назвать маршрутизатор play framework для передачи этих запросов? Я планировал использовать нечто похожее, как то, что рекомендуется для модульных тестов:
@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<? extends play.core.Router.Routes>)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<? extends play.core.Router.Routes> 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, чтобы добраться до него), чем для копирования вышеуказанного кода? Я также хотел бы дать возможность выполнять пакетные вызовы параллельно или последовательно... Я предполагаю, что создание экземпляров только одного Routes
с использованием загрузчика классов было бы проблематичным?
Вы можете использовать следующий вызов метода для маршрутизации ваших поддельных запросов: Play.current.global.onRouteRequest
. Пожалуйста, посмотрите это сообщение для полного примера: http://yefremov.net/blog/play-batch-api/
Вы можете, вероятно, использовать WS API для этого, но лично я бы просто создал частные методы для сбора данных и использования их как из "одиночных", так и "пакетных" действий - это будет быстрее.
batch
действии вы можете сначала собрать т.е. список идентификаторов для выборки, а затем выполнить один запрос и построить возвращаемый объект