Я хочу создать структуру URL-адресов для моего API с интерфейсом Web-интерфейса Vert.x, который дает понять, как некоторые объекты "содержатся" внутри других объектов и как вы "проходите путь сущности", чтобы найти дочерние сущности, поэтому я подумываю использовать что-то подобное, чтобы обратиться к "великому ребенку" (я не ожидаю ничего более глубокого, чем великий ребенок):
GET /entity/:parent_id/sub-entity/:child_id/subsub-entity/:grandchild_id
Поэтому обычно моя конфигурация Router
будет выглядеть примерно так:
router.get("/entity/:parent_id/sub-entity/:child_id/subsub-entity/:grandchild_id")
.handler(r -> {
HttpServerRequest req = r.request();
Minipart p = Entities.get(req.getParameter("parent_id"))
.getPart(req.getParameter("child_id"))
.getMinipart(req.getParameter("grandchild_id"));
// do something with p
});
Когда я добавляю много операций (каждый класс сущности на каждом уровне имеет каталог и создает операции, а каждый экземпляр сущности уровня получает, обновляет и удаляет операции, а также несколько других лакомых кусочков), мой класс маршрутизатора становится очень большим.
Я думал об использовании суба-маршрутизаторов, чтобы разгрузить управление подобъектом вниз линии, поэтому Entities
Router
конфигурация может сделать:
router.mountSubRouter("/entity/:parent_id/sub-entity", PartsRouter.init(vertx));
и затем PartsRouter
может делать:
router.get("/:child_id").handler(r -> {
String parentEntityId = r.request().getParameter("parent_id");
Entity parent = Entities.get(parentEntityId);
String myid = r.request().getParameter("child_id");
Part myself = parent.getPart(myid);
// do something with myself
});
Но когда я пытаюсь это сделать и пытаюсь получить доступ к операциям sub-router, я получаю ошибку 404 от Vert.x...
Обновить:
По-видимому, Vert.x явно не поддерживает это - он выдал исключение, что мой код оболочки только что зарегистрировался и проигнорирован, сказав:
java.lang.IllegalArgumentException: Can't use patterns in subrouter mounts
Итак, есть ли другой способ достичь того, что я пытаюсь сделать (разделить большую конфигурацию маршрутизатора на правильную иерархию классов)?
Я могу представить два способа решения вашей проблемы:
Первый из них должен состоять в том, чтобы иметь начальный обработчик, который обрабатывает общую часть запроса и вызывает следующий, поэтому следующий будет продолжен там, где первый остановлен, например:
router.route("/entity/:parent_id/sub-entity", ctx -> {
// common part here...
ctx.next();
});
А потом:
router.route("/entity/:parent_id/sub-entity/:child_id", ctx -> {
String parentEntityId = r.request().getParameter("parent_id");
Entity parent = Entities.get(parentEntityId);
String myid = r.request().getParameter("child_id");
Part myself = parent.getPart(myid);
// do something with myself
});
В качестве альтернативы вы можете использовать внутренние переадресации, поэтому сначала обрабатываете исходный код, а вместо вызова next()
вы перенаправляете на другой URL-адрес. В этом случае вы должны сохранить в контексте то, что хотите повторно использовать, поскольку запрос будет перезапущен в новом месте.
ctx.next()
, и это полезно, но ваше решение все еще не решает необходимость иметь полный путь со всеми аргументами в каждой регистрации маршрута, у меня в настоящее время есть около 20 таких вызовов API и Я ожидаю как минимум в 4 раза больше.reroute()
и указать его на универсальный обработчик, или, поскольку путь является простой строкой, используйте константу String и объедините различие в каждом обработчике.