読者です 読者をやめる 読者になる 読者になる

@Konboi memo

主に技術に関してつらつらと。

MojoliciousでJSONを返すAPIを作ってたらはまった

ルーティングの設定 App.pm

package App;
use Mojo::Base 'Mojolicious';

# This method will run once at server start
sub startup {
  my $self = shift;

  # Documentation browser under "/perldoc"
  $self->plugin('PODRenderer');

  # Router
  my $r = $self->routes;

  # Normal route to controller
  $r->get('/')->to('example#welcome');
  $r->get('/api/ping')->to('api#ping');
}

1;

Controller側 App/API.pm

package App::API;

use strict;
use warnings;
use utf8;
use Mojo::Base 'Mojolicious::Controller';

sub ping {
    my $self = shift;

    my $json = { 'name' => 'hello api'};

    $self->render_json( $json );
}

1;

こんな感じで
/api/ping にきたら json を返すように書いたつもりだった。

デフォルトのを見る限りこういう構成なので。

$r->get('/')->to('example#welcome');
          #コントローラー名#メソッド名

で、ログを見てるとこんな感じでログが出されてた。

ログ

[Wed Sep  5 17:42:51 2012] [debug] Class "App::Api" is not a controller.
[Wed Sep  5 17:42:51 2012] [debug] Rendering template "api/ping.html.ep".

ログをみて...

App::Api はコントローラーじゃない??
                  ↓
んー、でもちゃんと Mojolicious::Controllerを useしてるもんな...
                  ↓
しかしなんで、App::API じゃなくて App::Api なんだ..?
                  ↓
                  ↓
                  ↓
            ( ◔ิω◔ิ) { まさか....

ってな事でダメ元でこんな感じで書きなおしてみた。

    $r->get('/api/ping')->to('api#ping');
                     ↓
    $r->get('/api/ping')->to('API#ping');

上手くいった。
こんな感じでそれぞれのコントローラー名を正しく書けばなんら問題ないのか。

    $r->get('/api/ping')->to('API#ping');
    $r->get('/api/ping')->to('Example#ping');

また1つ勉強になった。

追記 2012/09/05/19:00

    $r->get('/api/ping')->to('Example#ping');

こうするとtemplateの方のディレクトリ名も Example/
にしないといけないので特に理由がない場合は小文字でコントローラー名を書くべきですね