Как работает Mojolicious `under`?

#perl #mojolicious

#perl #mojolicious

Вопрос:

Из документации:

Все следующие маршруты оцениваются только в том случае, если обратный вызов вернул истинное значение.

Что это following значит?

  1. Группа маршрутов, которые находятся только под этим
  2. Маршруты, которые объявляются позже в коде, после этого under

Также я не понимаю, что происходит в следующем сценарии:

 perl -Mojo -E '
  app->routes->under("/", sub{ warn "R1"; return undef })->get("/r1" => {text => "r1" }); 
  app->routes->under("/", sub{ warn "R2"; return undef })->get("/r2" => {text => "r2" }); 
  app->start;
' 
get /r2
 

Здесь ничего не было сопоставлено, так что я должен получить 404 то же самое, что и в следующем приложении:

 perl -Mojo -E 'app->start;' get /r2
 

Комментарии:

1. Я не совсем понимаю ваш вопрос. Ваш первый пример только предупреждает (правильно) для обоих маршрутов, но не возвращает содержимое в нижнем регистре. Это потому, что обратные вызовы должны возвращать истинное значение. Избавьтесь от return undef и сделайте 1 вместо этого, чтобы увидеть как предупреждение, так и текст.

2. @simbabque: в первом примере команда никогда не возвращается (это проблема). Я возвращаюсь, undef потому что они ограничены только авторизованными пользователями. Как в примере

3. @simbabque: Итак, оба маршрута ограничены, ничего не было сопоставлено. Должен ли я получить 404 или какую-то ошибку?

4. Вероятно, вы должны перенаправить на страницу входа в систему.

5. Или отобразите какое-то сообщение, — в любом случае возврат undef ничего не отобразит.

Ответ №1:

Ваше предположение, что здесь ничего не было сопоставлено, неверно. У вас есть маршрут для /r2 . Обратные вызовы, связанные с этим маршрутом, образуют цепочку, в которой каждый обратный вызов может выдавать ответ или передавать ответственность следующему обратному вызову в цепочке, возвращая true .
Если вы запустите этот код из приложения с включенным ведением журнала (logfile log/development.log по умолчанию), вы увидите

[timestamp] [6389] [debug] [Ere90x2U] Nothing has been rendered, expecting delayed response

указывает на то, что ваши обратные вызовы вернулись без рендеринга чего-либо.

Обычно ваш under обратный вызов используется для исключения некоторых распространенных действий, таких как проверка прав доступа (см. Руководство ).
В этом примере обратный вызов перенаправляет на страницу входа в систему, если это необходимо, или возвращает true для передачи управления следующему обратному вызову в цепочке:

   my $logged_in = $r->under(sub ($c) {
    return 1 if $c->session('user');
    $c->redirect_to('index');
    return undef;
  });
  $logged_in->get('/protected');
 

На самом деле, здесь обратный вызов for /protected является неявным, и protected.html.ep будет отображен соответствующий шаблон.

Комментарии:

1. Это полезно. Но для приложения oneline журнал не создается, и сообщение отладки не отображается

2. Да, это правда.

3. @EugenKonkov каков вариант использования однострочных приложений? Конечно, если вам нужно более сложное поведение, например, факторинг подобного поведения, вы бы вложили больше, чем очень длинную одну строку.

4. @simbabque: они предназначены для изучения того, как under это работает