【问题标题】:Mounting a Vert.x sub-router on a path with path parameters在带有路径参数的路径上挂载 Vert.x 子路由器
【发布时间】:2016-09-21 13:31:11
【问题描述】:

我想为我的 Vert.x Web 驱动的 API 创建一个 URL 结构,以明确某些实体是如何“包含”在其他实体中的,以及您如何“遍历实体路径”来查找子实体,所以我考虑用这样的东西来称呼“孙子”(我不希望有比孙子更深的东西):

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
    });

当我添加了很多操作(每个级别的每个实体类都有catalog和create操作,每个级别的实体实例都有get,update和delete操作,以及其他一些花絮),我的路由器类变得真正大的。

我正在考虑使用子路由器来卸载子实体管理,所以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
});

但是当我尝试这样做并尝试访问子路由器操作时,我从 Vert.x 收到 404 错误...

更新:

显然 Vert.x 明确不支持这一点 - 它引发了我的包装代码刚刚记录并忽略的异常,说:

java.lang.IllegalArgumentException: Can't use patterns in subrouter mounts

那么,有没有另一种方法来实现我想要做的事情(将大型路由器配置拆分为适当的类层次结构)?

【问题讨论】:

    标签: java url routes vert.x path-parameter


    【解决方案1】:

    我可以想象两种解决问题的方法:

    第一个是有一个初始处理程序来处理请求的公共部分并调用下一个,因此以下一个将在第一个停止的地方继续,例如:

    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() 方法并将其指向通用处理程序,或者由于路径是纯字符串,请使用字符串常量并将差异连接到每个处理程序。
    • 我最终实现了类似于您的原始答案的东西。我所做的是实现一个类,该类基于一组嵌套类自动生成route() 路径,其中每个类都调用API 以将自身添加到“父路由”之上。这有点复杂但很有用且富有表现力(我会看到将其作为开源发布),尽管我确实希望 Vert.x 能够避免这种麻烦并在mountSubrouter() 中实现模式。这里肯定缺少 API。
    • 如果有人仍然对编程解决方案感兴趣,我已经发布了一个库,可以将其作为更大模式的一部分进行处理。它是开源的,你可以在这里找到它:github.com/GreenfieldTech/irked
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多