Конфигурация маршрутизатора Vertx

Я новичок в 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. Не имеет значения, находится ли параметр в конце пути или посередине.

То же самое и с путями, оканчивающимися звездой. Эта функция не работает, если путь содержит параметр.


person Tammeuh    schedule 07.12.2015    source источник


Ответы (1)


Вы можете использовать регулярное выражение, чтобы избежать дублирования проверки правильности 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();

    }

}

Чтобы проверить идентификатор задания, я бы сделал что-то подобное:

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);
person Sebastian Coetzee    schedule 10.12.2015