Пакетные HTTP-запросы в Play! Framework

1

У меня есть текущий набор реализованных маршрутов (например):

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 с использованием загрузчика классов было бы проблематичным?

Теги:
playframework
playframework-2.2

2 ответа

2
Лучший ответ

Вы можете использовать следующий вызов метода для маршрутизации ваших поддельных запросов: Play.current.global.onRouteRequest. Пожалуйста, посмотрите это сообщение для полного примера: http://yefremov.net/blog/play-batch-api/

  • 0
    Спасибо тебе за это.
0

Вы можете, вероятно, использовать WS API для этого, но лично я бы просто создал частные методы для сбора данных и использования их как из "одиночных", так и "пакетных" действий - это будет быстрее.

  • 0
    Я рассматривал это (в отчаянии). Я хотел бы избежать необходимости отправлять дополнительные HTTP-запросы на мой сервер ... потому что в конце концов одно большое преимущество конечной точки пакета состоит в том, чтобы выполнять много вызовов с использованием только одного HTTP-запроса.
  • 0
    Поэтому просто перейдите ко второму предложенному подходу, в вашем batch действии вы можете сначала собрать т.е. список идентификаторов для выборки, а затем выполнить один запрос и построить возвращаемый объект
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню