Mojoliciousの開発者にとって便利で楽しい

HajoのMojoliciousについては、すでに何度か書いています。 フレームワークは正常に開発されており、私の意見では、毎日の急速な開発にとってより便利になっています。



カットの下で、フレームワークを操作するためのいくつかのトリックを集めました。これは私の人生を真剣に単純化し、おそらく他の誰かに役立つでしょう。



以上



Mojoliciousのルートメソッドには、 over()メソッドがあります。 このメソッドを使用すると、ルートに条件を課すことができるため、条件を満たした場合にのみ、クライアントはルートで指定されたコントローラーにアクセスできます。 これはすでにパワーマン によって書かれました 。 このメソッドは、たとえば次のように使用できます。



ファイルAppName.pm

package AppName; use Modern::Perl; use Mojo::Base 'Mojolicious'; use utf8; # This method will run once at server start sub startup { my $self = shift; $self->plugin('AppName::Helpers::Core'); #          my $r = $self->routes; #   #      #     user_id      isAdmin,   -  $r->add_condition( isAdmin => sub { my ($route, $c, $captures, $pattern) = @_; return 1 if $c->isAdmin($c->session->{'user_id'}); return undef; } ); #  GET- /users     users  sd   isAdmin -  $r->get('/users')->over(isAdmin => 1)->to('sd#users'); #      -      ,      -    404 $r->any('/(*everything')->to('user#main'); } 1;
      
      







ヘルパー自体のコードは次のようになります(ユーザーが少ないため、特権を構成に直接格納します)。

 package AppName::Helpers::Core; use base 'Mojolicious::Plugin'; use Modern::Perl; sub register { my ($self, $app) = @_; $app->helper( isAdmin => sub { #   ,        # invocation: # $whatever->isAdmin($user_login) # outputs: 1|2, undef my ($self, $user_login) = @_; return 1 if $user_login eq $user foreach (@{$self->config->{PrivilegedUsers}->{Administrators}}); return 2 if $user_login eq $manager foreach (@{$self->config->{PrivilegedUsers}->{Managers}}); return undef; } ); } 1;
      
      







Mojolicious ::プラグイン::認証



このプラグインは、その使いやすさから、ユーザー認証を実装する最も便利な方法のように思えました。 プラグインを使用するには、通常のperlモジュールとしてAppName.pmに接続し、次のようなものを追加するだけで十分です。



 $self->plugin('authentication', autoload_user => 1, #     ,    $c->current_user   load_user => sub { my $self = shift; my $uid = shift; return { 'id' => $uid, 'name' => $self->session->{'user_id'}, } if $uid; return undef; }, validate_user => sub { #    my $self = shift; my $username = shift || ''; my $password = shift || ''; my $extradata = shift || {}; my $user = $self->APIrequest(...); #        -  ,     -      if (ref($user) eq 'HASH') { $self->error("API internal error while logging in user: ".$username); return undef; } if ($user->[0] !~ m/^Error:/) { $self->session->{'user_id'} = $username; return $user->[0]; } $self->info("Login for user '$username' failed: $user->[0]"); return undef; } );
      
      







プラグインはルートの条件もエクスポートし、上記のルートは次のように書き換えることができます。

 $r->get('/users')->over(authenticated => 1)->over(isAdmin => 1)->to('sd#users');
      
      







同時に、コントローラー内部のことを考える必要はありません。ユーザーが条件を満たさない場合、ユーザーはこれらのコントローラーに入ることはありません。



Mojolicious ::コマンド



このメカニズムにより、アプリケーションでコンソールコマンドを使用できます。

主な魅力は、アプリケーションのコンテキストで実行され、内部にアクセスできる独自のコマンドを追加できることです( ドキュメントを参照 )。 したがって、たとえば、クラウンによって、アプリケーションにローカルに保存されたデータを会社の内部Webサービスと同期します。



 $ ./AppName GetCMDB -h Usage: APPLICATION GetCMDB
      
      







フック



Mojoliciousには、特定のイベントによってトリガーされ、アプリケーションの操作に影響を与えることができる多くのフックが用意されています。

私がいつも使っているのはbefore_renderです。 このフックは、コントローラーがデータをテンプレートに転送する前に起動し、2つの主な問題を解決できます。



エラー診断


レンダラー呼び出しからの引数はフックから利用できます。コントローラーがエラー500を「フォール」して表示することを決定した場合、問題の原因に関する情報を含む匿名ハッシュ{例外}があります。 エラーを「キャッチ」し、RedmineのAPIを介してレポートし、アプリケーションを反応させるために使用します。問題を修正するか、エラーメッセージを表示します。



ところで、エラーを報告するプロセスで、アプリケーションはディスク上のファイルテンプレート/ exception.production.html.epを探します-エラーページのHTMLテンプレート。 テンプレートがない場合は、ボックス化されたものが使用され、ユーザーを驚かせる可能性があります。



フロントエンドの問題の診断


コントローラーのコンテンツ全体がフックで使用できるため、コントローラーの操作に関する必要なデータをそこから直接収集し、stash()を介してクライアントに渡すことができます。 フロントエンドが意図したとおりに動作せず、クライアントに送信されるデータ(たとえばjson)が送信されるべきものと一致するかどうかが問題になる場合に便利です。



フックコードはAppName.pmに追加され、次のようになります。

 $self->hook(before_render => sub { my ($c, $args) = @_; if ($args->{'exception'}) { #    ,   %snapshot      my %snapshot = map {$_ => $c->stash->{$_}} grep {!/mojo.active_session|mojo.captures|mojo.routed|mojo.secrets|mojo.started|^config$|^exception$/ and defined $c->stash->{$_}} keys %{$c->stash}; #   Redmine    $c->RedmineReport(); } #       $c->stash(snapshot => { map {$_ => $c->stash->{$_}} grep {!/mojo.active_session|mojo.captures|mojo.routed|mojo.secrets|mojo.started|^config$|^exception$/ and defined $c->stash->{$_}} keys %{$c->stash} }); return; });
      
      







大量のデータ



アプリケーションが大きい場合、コントローラーとヘルパーの複数のファイルが含まれている可能性があります(プラグインとして接続されています)。 デフォルトでは、すべてのMojoファイルはAppName / libで検索されるため、1つのディレクトリで多くの視覚的なゴミが発生しないように、ファイルをサブディレクトリに分割し、たとえば次のようにAppName.pmに添付できます。



 #     Core.pm, Lib.pm, CMDB.pm   AppName/lib/Helpers $self->plugin('AppName::Helpers::Core'); $self->plugin('AppName::Helpers::Lib'); $self->plugin('AppName::Helpers::CMDB'); #       AppName/lib/Controllers $r = $r->namespaces(['AppName::Controllers']);
      
      







結論の代わりに



いつものように、Perlとその上に構築されたソリューションには、問題を簡単、迅速かつ美しく解決する多くの方法があります。 私は自分の方法が最も優れているとは言いませんが、少なくとも私の仕事には非常に役立ちます。



All Articles