3

我正在使用 Apache 和 Perl (modperl),以及处理程序来处理请求。我是新手,我不太确定如何以合理的方式进行布局。

现在我有以下内容:

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.pm 来进行所有用户管理?一个 Story.pm 的故事?

4

2 回答 2

6

您可能对来自 CPAN 的优秀CGI::Application框架感兴趣。尽管它的名字,它在普通 CGI 和 mod_perl 下都可以工作。它旨在使设置 Web 应用调度表的任务变得非常简单。加入CGI::Application::Dispatch,你会得到很好的类似 REST 的 URL。

于 2009-06-24T20:28:16.950 回答
2

对于最近的一个项目,我编写了一个自定义配置处理程序,它实现了一个新的 ResourceURI 配置设置。这让我可以像这样将配置行放入 httpd.conf:

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

这三个参数是我的资源类名称、资源可以响应的 HTTP 方法列表以及与资源的 URI 匹配的正则表达式。

自定义配置类将这些行中的每一行替换为如下块:

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);
}

现在你只需要使用你的资源逻辑(包括如何格式化表示)来实现 Resource::* 类,以及使用名为 GET、HEAD、POST 等方法的 Handler::* 类,并让它们使用 $r 和 $resource 来处理请求。

对于你需要的每一个新资源,你添加一行配置,实现一个 Handler 类(我发现它通常可以是一个从通用基类继承的几乎空的模块),并实现一个包含大部分的 Resource 类代码。我还发现在处理对另一种资源的请求的上下文中,我经常需要创建一个资源对象。这就是为什么我的资源构造函数为 uri 使用单独的参数,而不是仅仅从 $r 获取 uri。如果我在 Resource::Foo 并且我需要一个 Resource::Bar 对象,我可以说 my $bar = Resource::Bar->new($r, '/bars/1234'); 它使用客户端将使用的相同 URI 创建 Bar 对象。

于 2009-06-30T05:24:31.957 回答