Perl REST макет потока - PullRequest
       12

Perl REST макет потока

3 голосов
/ 24 июня 2009

Я использую 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 для всего управления пользователями? A Story.pm для историй?

Ответы [ 2 ]

6 голосов
/ 25 июня 2009

Вас может заинтересовать превосходная CGI :: Application платформа от CPAN. Несмотря на название, он работает как под обычным CGI, так и под mod_perl. Он разработан, чтобы упростить задачу настройки таблиц отправки веб-приложений. Добавьте CGI :: Application :: Dispatch , и вы получите хорошие REST-подобные URL.

2 голосов
/ 30 июня 2009

Для недавнего проекта я написал собственный обработчик конфигурации, в котором реализован новый параметр конфигурации 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 :: * с помощью логики ресурсов (включая способ форматирования представлений) и классы Handler :: * с методами с именами GET, HEAD, POST и т. Д., Чтобы они использовали $ r и $ ресурс для обработки запросов.

Для каждого нового ресурса, который вам нужен, вы добавляете одну строку конфигурации, реализуете один класс Handler (который, как я обнаружил, часто может быть почти пустым модулем, унаследованным от базового базового класса), и реализуете один класс Resource, который содержит основная часть кода. Я также обнаружил, что мне часто нужно создавать один объект ресурса в контексте обработки запроса на другой ресурс; Вот почему мои конструкторы ресурсов принимают отдельный аргумент для URI вместо того, чтобы просто получить URI из $ r. Если я нахожусь в Resource :: Foo и мне нужен объект Resource :: Bar, я могу сказать, что мой $ bar = Resource :: Bar-> new ($ r, '/ bars / 1234'); который создает объект Bar, используя тот же URI, который использовал бы клиент.

...