【问题标题】:Perl REST flow layoutPerl REST 流布局
【发布时间】:2010-11-05 15:20:12
【问题描述】:

我正在使用 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?

【问题讨论】:

    标签: perl apache model-view-controller rest mod-perl


    【解决方案1】:

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

    【讨论】:

    • 谢谢,我正在努力学习一下。我将如何布局应用程序的其余部分?
    • 我通常会尝试考虑非常具体的“应用程序”,每个应用程序都有少量的“屏幕”。因此,在您的示例中,我通常会为“用户”应用程序编写一个模块,该模块将具有屏幕(CGI 应用程序行话中的运行模式)来编辑他们的个人资料、更改他们的密码等。通常我尝试将每个模块保持为五个或更少的运行模式和大约 300 行代码。
    • 谢谢!我实际上是这样做的,但真的不确定这是否是“好”的方式..
    【解决方案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 和 $资源来处理请求。

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

    【讨论】:

      猜你喜欢
      • 2012-04-08
      • 2012-10-02
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      相关资源
      最近更新 更多