Mercurial > pub > Impl
view Lib/IMPL/Web/Handler/RestController.pm @ 216:e9fd7ff3f54c
sync
author | sergey |
---|---|
date | Thu, 09 Aug 2012 17:24:07 +0400 |
parents | d6e2ea24af08 |
children | 47f77e6409f7 |
line wrap: on
line source
package IMPL::Web::Handler::RestController; use strict; use IMPL::lang qw(:declare :constants); use IMPL::declare { require => { Exception => 'IMPL::Exception', ArgumentExecption => '-IMPL::InvalidArgumentException', HttpException => 'IMPL::Web::Exception', NotFoundException => 'IMPL::Web::NotFoundException' }, base => { 'IMPL::Object' => undef, 'IMPL::Object::Autofill' => '@_', 'IMPL::Object::Serializable' => undef } }; BEGIN { public property root => PROP_GET | PROP_OWNERSET; public property contract => PROP_GET | PROP_OWNERSET; } sub CTOR { my ($this) = @_; die ArgumentException->new("root") unless $this->root; die ArgumentException->new("contract") unless $this->contract; } sub Invoke { my ($this,$action) = @_; my $query = $action->query; my $method = $query->request_method; #TODO: path_info is broken for IIS my $pathInfo = $query->path_info; my @segments; if (length $pathInfo) { @segments = split /\//, $pathInfo, -1; # keep trailing empty string if present # remove first segment since it's always empty shift @segments; my ($obj,$view) = (pop(@segments) =~ m/(.*?)(?:\.(\w+))?$/); push @segments, $obj; } my $res = $this->contract->Transform($this->root, { id => '' } ); while(@segments) { my $id = shift @segments; $res = $res->FetchChildResource($id,$action); die NotFoundException->new($pathInfo,$id) unless $res; } $res = $res->InvokeHttpMethod($method,$action); } 1; __END__ =pod =head1 NAME C<IMPL::Web::Handler::RestController> - Транслирует запросы к ресурсам в вызовы методов. =head1 SYNOPSIS Использует контракты для преобразования стандартных C<REST> запросов в вызовы методов объектов. C<$ENV{PATH_INFO}> используется как путь к нужному ресурсу у которого будет вызван метод указанный в запросе. =head1 DESCRIPTION =head2 Resource model Ресурсы имеют иерархическую структуру, аналогичную файлам и каталогам, которая описывается контрактом, также контрак описывает то, как должны обрабатываться методы C<HTTP> запроса, такие как C<GET> и C<POST>. За корректность реализации данных методов отвечает разработчик. Каждый ресурс представляет собой коллкецию вложенных ресурсов, путь указанный в C<HTTP> запросе разбивается на части, затем каждый сегмент последовательно используется для поиска дочернего ресурса. При обработки первого сегмента используется корневой ресурс. Корневой ресурс должен существовать всегда. =head2 Contract Контрактом может быть любое преобразование которое определяет соответсвие между объектами приложения и ресурсами, доступными через протокол C<HTTP>. =cut