2009-06-24 1 views
3

私はリクエストを処理するためにハンドラとともにApacheとPerl(modperl)を使用しています。私はこれを初めて知っており、賢明なやり方で物事をどのように敷くかについてはあまりよく分かりません。Perl RESTのフローレイアウト

今、私は次のようにあります

package MyClass::Handler; 

use warnings; 
use strict; 
# includes 

our %action = ( 
    'a' => \&a, 
    # And more 
); 

sub handler { 
    my $a = shift; 
    my $r = Apache2::Request->new($a); 

    # Do things 

    return Apache2::Const::OK(); 
} 

は、私はそれぞれの「空間」に別のファイルを持っているべきですか? stackoverflowをテンプレートとして使用すると、すべてのUser管理にUser.pmが必要ですか?物語のための物語.pm

答えて

6

CPANの優れたCGI::Applicationフレームワークに興味があるかもしれません。その名前にもかかわらず、通常のCGIとmod_perlの両方で動作します。これは、Webアプリのディスパッチテーブルを非常に簡単にセットアップする作業を行うように設計されています。 CGI::Application::Dispatchを投げれば、良いRESTのようなURLが得られます。

+0

ありがとう、私はそれを少し勉強しようとしています。私はどのようにアプリケーションの残りの部分をレイアウトしますか? – Timmy

+1

私は一般に、少数の「スクリーン」を持つ非常に特殊な「アプリケーション」の観点から考えようとします。あなたの例では、私は通常、自分のプロファイルを編集したり、パスワードを変更したりするためのスクリーン(CGI-appの専門用語ではランモード)を持つ "user"アプリケーション用のモジュールを書くつもりです。 一般的に私は各モジュールランモードが5つ以下、コードが約300行になります。 – friedo

+0

ありがとう!私は実際にこのようにしていますが、これが「良い」方法であるかどうかは実際にはわかりません。 – Timmy

2

最近のプロジェクトでは、新しいResourceURI設定を実装したカスタム構成ハンドラを作成しました。これは私はこのようにhttpd.confのに設定行を入れてみましょう:

ResourceURI SomeResource GET,POST,DELETE "^/...$" 

三つの引数は、私のリソースクラス名、リソースが応答できるHTTPメソッドのリスト、およびURI(Sに一致する正規表現です)を指定します。

カスタム設定クラスは、このようなブロックと、これらの行のそれぞれを置き換える:

PerlModule Handler::{resource class} 
PerlModule Resource::{resource class} 

<Location ~ "{uri regex}"> 
    Order allow,deny 
    Allow from all 

    <LimitExcept {allowed methods}> 
     Order deny,allow 
     Deny from all 
    </LimitExcept> 

    SetHandler modperl 
    PerlHandler Handler 

    PerlSetVar Resource {resource class} 
</Location> 

これが私のクラスをロードするの面倒を、Apacheが無効なメソッドを拒否することができます、にルーティングするどのリソースを示すためにフラグを設定しますすべてのリクエストをHandler :: handler()関数で渡します。

package Handler; 

sub handler { 
    my $r = shift; 
    my $resource_class = 'Resource::' . $r->dir_config('Resource'); 
    my $handler_class = 'Handler::' . $r->dir_config('Resource'); 
    my $resource = $resource_class->new($r, $r->uri); 
    return Apache2::Const::HTTP_NOT_FOUND unless $resource; 
    my $method = $r->method(); 
    return Apache2::Const::HTTP_NOT_IMPLEMENTED 
     unless $handler_class->can($method); 
    return $handler_class->$method($r, $resource); 
} 

今、あなただけの(表現をフォーマットする方法を含む)リソース・ロジックとリソース:: *クラスを実装する必要がある、とハンドラGETという名前のメソッドを持つ:: *クラス、HEAD、POSTなど、それらを使用してい$ rと$ resourceを使用してリクエストを処理します。

必要な新しいリソースごとに、1行の設定を追加し、1つのHandlerクラス(一般的な基本クラスを継承するほとんど空のモジュールであることがわかっている)を実装し、コードの大部分また、別のリソースの要求を処理するコンテキストで1つのリソースオブジェクトを作成する必要があることもわかりました。そのため、私のリソースコンストラクタは、$ rからuriを取得するのではなく、uriを別の引数として取ります。私がResource :: Fooにいて、Resource :: Barオブジェクトが必要な場合は、$ bar = Resource :: Bar-> new($ r、 '/ bars/1234')と言うことができます。これは、クライアントが使用するのと同じURIを使用してBarオブジェクトを作成します。