我是vertx的新手,所以可能我做错了什么。我正在尝试实现以下路线:
router.get("/api/users/").handler(this::getUsers);
router.route("/api/users/:username*").handler(this::checkUsername);
router.get("/api/users/:username/").handler(this::getUser);
router.put("/api/users/:username/").handler(this::addUser);
router.get("/api/users/:username/assignments/").handler(this::getAssignments);
router.post("/api/users/:username/assignments/").handler(this::addAssignment);
router.route("/api/users/:username/assignments/:assignmentId/").handler(this::checkAssignmentId);
router.get("/api/users/:username/assignments/:assignmentId/").handler(this::getAssignment);
这是避免在所有处理程序中重复此逻辑的正确方法吗?
我正在尝试链接处理程序,其中checkUsername
处理程序从路径中读取username
参数,尝试查找相应的用户,并将该用户放入上下文中。如果没有找到用户,则返回状态代码400。否则将调用下一个处理程序。我想将相同的原理应用于assignmentId
参数。
在尝试实现这一点时,我相信我发现了路径的问题,更具体地说是尾部的斜杠和星号。文档中指出会忽略尾部斜杠。当路径中存在参数时,这不是行为。在这种情况下,后面的斜杠很重要。如果路径定义包含一个,而请求没有,则vertx返回404。参数是否在路径的末端或在中间没有区别。
以星星结尾的路径也是如此。当路径包含参数时,此功能不起作用。
您可以使用正则表达式来避免重复checkUsername验证检查。我要做的是,我会有一个这样的方法来检查用户名是否有效:
private void checkUsername(RoutingContext routingContext){
//The "param0" is the capture group of the regular expression. See the routing config below.
if (isValidUsername(routingContext.request().getParam("param0"))){
routingContext.next();
} else {
routingContext
.response()
.setStatusCode(400)
.end();
}
}
为了检查任务ID,我会做类似的事情:
private void checkAssignmentId(RoutingContext routingContext){
if (isValidAssignmentId(routingContext.request().getParam("assignmentId"))){
routingContext.next();
} else {
routingContext
.response()
.setStatusCode(400)
.end();
}
}
尽量避免在你的路径上留下斜线。我会把路由处理程序的分配改成这样:
router.get("/api/users").handler(this::getUsers);
//By the way, you really want to be using a POST request when adding users just to stick to the principles of REST.
//When you are sending a POST request there is no need to put the username in the URI. You can have it in the request body.
//Please ensure you validate this username using the same validation helper used in your other validations.
router.post("/api/users").handler(this::addUser);
//Use regular expression to match all "/api/users/:username*" URIs
router.routeWithRegex("\/api\/users\/([^\/]+)").handler(this::checkUsername);
router.get("/api/users/:username").handler(this::getUser);
router.get("/api/users/:username/assignments").handler(this::getAssignments);
router.post("/api/users/:username/assignments").handler(this::addAssignment);
router.route("/api/users/:username/assignments/:assignmentId").handler(this::checkAssignmentId);
router.get("/api/users/:username/assignments/:assignmentId").handler(this::getAssignment);