SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Webアプリケーションフレームワーク「Catalyst」入門

初めてのCatalyst入門(3)
処理の入り口はアクション

コントローラのURLパスとアクションの定義方法

  • X ポスト
  • このエントリーをはてなブックマークに追加

組み込みアクション

 Catalystでは、リクエスト処理を実行する中で、特別な動作をする組み込みアクションが5つ用意されています。これらのアクションを定義した場合には「$c->forward」などで明示的に呼び出さなくても、Catalystの側で自動的に呼び出されます。

default

 「default」アクションは、他にマッチするアクションがない場合に呼び出されます。「Root.pm」にデフォルトで作成されるdefaultアクションでは、「Page not found」を表示し、404を返します。

 defaultアクションはそれぞれのコントローラで上書き(オーバーライド)できます。例えば「Bar.pm」にdefaultアクションを定義し、ネームスペースが「foo/bar」以下の存在しないパスを指定した場合には、「Bar.pm」モジュールで定義したdefaultアクションが呼び出されます。

 古いバージョンのCatalystでは「default :Private」と定義されることがありますが、これらの違いは次のようになります。

 例として、Bar.pmにdefaultアクションを追加した場合について考えます。ここで次のURLを指定した場合の動作について説明します。

  • http://<ホスト名またはIPアドレス><:Port>/foo/bar/aaa/bbb

(1)default :Path

 ネームスペースからの相対パスが引数になるため、「aaa/bbb」が引数となります。

(2)default :Private

 コントローラに関係なく、ルートからの相対パスが引数になるため、「foo/bar/aaa/bbb」が引数となります。

index

 「index」アクションはdefaultアクションとよく似ていますが、引数を取らない優先順位が高い、という点で異なります。

 一般的には、コントローラのエントリポイントとして使用され、Welcomeページの表示やデータの一覧を表示する処理を定義します。

begin

 「begin」アクションは、リクエストの最初に呼び出され、またコントローラで上書きできます。beginアクションでは、必要なデータを作成したりする場合に使用されます。例えばbeginアクションで、UserAgentからクライアントの端末が携帯電話かそれ以外かを判定し、そのフラグをStashに登録しておけば、他のアクションでは毎回端末の種別チェックをする必要が無くなります。

[リスト14]beginアクションでUserAgentによりテンプレートパスを変更する例
package HelloC::Controller::Root;

# 省略

sub begin : Private {
  my ( $self, $c ) = @_;

  # (1)リクエストのUserAgentから、携帯電話かそれ以外かを判定
  my $user_agent = $c->req->user_agent;
  $c->stash->{is_mobile} = 0 or 1;
}

sub index :Path :Args(0) {
  my ( $self, $c ) = @_;

  # (2)フラグによって携帯電話/PCかどうかを判定
  if ($c->stash->{is_mobile}) {
    # 携帯電話用の処理
  } else {
    # PC用の処理
  }
}

 上記の例では、次のような処理を行っています。

(1)リクエストのUserAgentから、携帯電話かそれ以外かを判定

 Catalyst::RequestからUserAgentを取得し、携帯電話かどうかを判定します。そして判定結果をStashに登録しています。

(2)フラグによって携帯電話/PCかどうかを判定

 indexアクションでは、Stashに登録された値に基づいて携帯電話かPCかを判定し、それぞれに依存した処理を実装します。

end

 「end」アクションはリクエストの最後に呼び出され、またコントローラで上書きできます。endアクションには、最後にまとめて行う処理を記述します。例えば各アクションごとにViewへのレンダリング処理を呼び出さなくても、endアクションにまとめて記述できます。デフォルトの「Root.pm」では、endアクションの定義が次のようになっています。

[リスト15]Root.pmのendアクション
package HelloC::Controller::Root;

# 省略

sub end : ActionClass('RenderView') {}

 ここでは、:ActionClassアトリビュートで指定したCatalyst::Action::RenderViewを使用することで、適切なViewの呼び出し処理を行っています。

auto

 「auto」アクションは、beginアクションの後に呼び出されますが、他のアクションと異なり、複数のコントローラで定義した場合でも上書きされません(すべてのautoアクションが順に呼び出されます)。

 autoアクションが複数のコントローラで定義されている場合、呼び出される順番はRootから始まり、順次下位のコントローラに向かって呼び出されます。

 例えば、次のコントローラにautoアクションが定義されている場合を考えます。

  • HelloC::Controller::Root
  • HelloC::Controller::Foo
  • HelloC::Controller::Foo::Bar

 この場合に「Foo::Bar」のアクションにマッチするリクエストがあった場合には、次の順序でautoアクションが呼び出されます。

  • HelloC::Controller::Root
  • HelloC::Controller::Foo
  • HelloC::Controller::Foo::Bar

 また、autoアクションで0を返した場合には、それ以降のアクション呼び出しが行われません。

 autoアクションでは、あるコントローラだけにとどめておきたい処理を記述します。例えば、「<MyApp>::Controller::User」と「<MyApp>::Controller::User::Bookmark」というコントローラを考えた場合、「<MyApp>::Controller::User」にはユーザーに関する前処理を、「<MyApp>::Controller::User::Bookmark」にはブックマークに関する前処理を記述することで、あちこちに実装が分散することを防ぐことができます。

[リスト16]Userコントローラのautoアクション例
package <MyApp>::Controller::User;

# 省略

sub auto :Private {
  my ( $self, $c ) = @_;

  # (1)ユーザ情報を取得
  $c->stash->{user_info} = ...
}
[リスト17]Bookmarkコントローラのautoアクション例
package <MyApp>::Controller::User::Bookmark;

# 省略

sub auto :Private {
  my ( $self, $c ) = @_;

  # (2)ユーザに関連するブックマークを取得
  my $user_info = $c->stash->{user_info};
  $c->stash->{bookmarks} = ...
}

sub index :Path :Args(0) {
  my ( $self, $c ) = @_;

  # (3)ブックマーク一覧を描画
  $c->stash->{template} = 'bookmark_list.tt';
}

 上記の例では、次のような処理を行っています。

(1)ユーザー情報を取得

 Userコントローラのautoアクションでは、セッションなどからユーザー情報を取得してStashに登録しています。

 ここでは、ブックマークなど他のコントローラに関する処理は実装していません。

(2)ユーザーに関連するブックマークを取得

 User::Bookmarkコントローラのautoアクションでは、Stashに登録されているユーザー情報を元にして関連するブックマークを取得し、Stashに登録しています。

 ユーザー情報に関する処理はUserコントローラに任せて、ここではブックマークに関する前処理のみを実装しています。

(3)ブックマーク一覧を描画

 indexアクションではブックマークの一覧を表示するためのテンプレートファイルを指定しています。

次のページ
まとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Webアプリケーションフレームワーク「Catalyst」入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 花田 善仁(ハナダ ヨシヒト)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4444 2009/10/30 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング