Perl REST 流程布局
我正在使用 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?
I'm using Apache and Perl (modperl), with Handlers to handle requests. I'm new to this, and I'm not quite sure how to lay things out in a sensible way.
Right now I have the following:
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();
}
Should I have a different file for each "space"? Using stackoverflow as a template, do I need a User.pm for all the User management? A Story.pm for stories?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能对优秀的 CGI::Application 感兴趣 来自 CPAN 的框架。 尽管它的名字如此,但它在普通 CGI 和 mod_perl 下都可以工作。 它旨在使设置 Web 应用程序调度表的任务变得非常简单。 加入 CGI::Application: :Dispatch 你会得到漂亮的类似 REST 的 URL。
You might be interested in the excellent CGI::Application framework from CPAN. Despite its name, it works both under normal CGI and mod_perl. It's designed to make the task of setting up web-app dispatch tables very simple. Throw in CGI::Application::Dispatch and you get nice REST-like URLs.
对于最近的项目,我编写了一个自定义配置处理程序,它实现了新的 ResourceURI 配置设置。 这让我可以将配置行放入 httpd.conf 中,如下所示:
三个参数是我的资源类名称、资源可以响应的 HTTP 方法列表以及与资源的 URI 匹配的正则表达式。
自定义配置类用这样的块替换每一行:
这负责加载我的类,让 Apache 拒绝无效方法,设置一个标志来指示要路由到哪个资源,并通过我的 Handler::handler 传递所有请求() 功能。
现在您只需要使用资源逻辑(包括如何格式化表示)来实现 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 对象。
For a recent project, I wrote a custom configuration handler which implemented a new ResourceURI config setting. This let me put configuration lines into httpd.conf like this:
The three arguments are my resource class name, the list of HTTP methods which the resource can respond to, and a regex that matches the URI(s) for the resource.
The custom configuration class replaces each of these lines with a block like this:
This takes care of loading my classes, lets Apache reject invalid methods, sets a flag to indicate which resource to route to, and passes all requests through my Handler::handler() function.
Now you just need to implement Resource::* classes with your resource logic (including how to format representations), and Handler::* classes with methods named GET, HEAD, POST, etc and have them use $r and $resource to handle the requests.
For every new resource you need, you add one line of configuration, implement one Handler class (which I've found can often be an almost empty module inheriting from a generic base class), and implement one Resource class which contains the bulk of the code. I've also found that I often need to create one resource object in the context of handling a request for another resource; that's why my resource constructors take a separate argument for the uri instead of just getting the uri from $r. If I'm in Resource::Foo and I need a Resource::Bar object, I can say my $bar = Resource::Bar->new($r, '/bars/1234'); which creates the Bar object using the same URI that a client would use.