Mercurial > pub > Impl
comparison Lib/IMPL/Web/Application/RestResource.pm @ 197:6b1dda998839
Added IMPL::declare, IMPL::require, to simplify module definitions
IMPL::Transform now admires object inheritance while searching for the transformation
Added HTTP some exceptions
IMPL::Web::Application::RestResource almost implemented
| author | sergey |
|---|---|
| date | Thu, 19 Apr 2012 02:10:02 +0400 |
| parents | a705e848dcc7 |
| children | 2ffe6f661605 |
comparison
equal
deleted
inserted
replaced
| 196:a705e848dcc7 | 197:6b1dda998839 |
|---|---|
| 1 package IMPL::Web::Application::RestResource; | 1 package IMPL::Web::Application::RestResource; |
| 2 use strict; | 2 use strict; |
| 3 | 3 |
| 4 use IMPL::lang qw(:declare :constants); | |
| 5 use IMPL::declare { | |
| 6 require => { | |
| 7 ForbiddenException => 'IMPL::Web::ForbiddenException' | |
| 8 }, | |
| 9 base => { | |
| 10 'IMPL::Object' => undef | |
| 11 } | |
| 12 }; | |
| 13 | |
| 14 BEGIN { | |
| 15 public property target => PROP_GET | PROP_OWNERSET; | |
| 16 public property methods => PROP_GET | PROP_OWNERSET; | |
| 17 public property childRegex => PROP_GET | PROP_OWNERSET; | |
| 18 public property list => PROP_GET | PROP_OWNERSET; | |
| 19 public property fetch => PROP_GET | PROP_OWNERSET; | |
| 20 public property insert => PROP_GET | PROP_OWNERSET; | |
| 21 public property update => PROP_GET | PROP_OWNERSET; | |
| 22 public property delete => PROP_GET | PROP_OWNERSET; | |
| 23 } | |
| 24 | |
| 25 sub GetHttpImpl { | |
| 26 my($this,$method) = @_; | |
| 27 | |
| 28 my %map = ( | |
| 29 GET => 'GetImpl', | |
| 30 PUT => 'PutImpl', | |
| 31 POST => 'PostImpl', | |
| 32 DELETE => 'DeleteImpl' | |
| 33 ); | |
| 34 | |
| 35 return $map{$method}; | |
| 36 } | |
| 37 | |
| 38 sub InvokeHttpMethod { | |
| 39 my ($this,$method,$child,$action) = @_; | |
| 40 | |
| 41 my $impl = $this->GetHttpImpl($method) || 'FallbackImpl'; | |
| 42 | |
| 43 return $this->$impl($child,$action); | |
| 44 } | |
| 45 | |
| 46 sub GetImpl { | |
| 47 my ($this,$id,$action) = @_; | |
| 48 | |
| 49 my $rx; | |
| 50 my $method; | |
| 51 if (length $id == 0) { | |
| 52 $method = $this->list; | |
| 53 } elsif ($method = $this->methods->{$id}) { | |
| 54 if (ref $method eq 'HASH' and not $method->{allowGet}) { | |
| 55 die ForbiddenException->new(); | |
| 56 } | |
| 57 } elsif($rx = $this->childRegex and $id =~ m/$rx/ ) { | |
| 58 $method = $this->fetch or die ForbiddenException->new(); | |
| 59 | |
| 60 $method = { | |
| 61 method => $method, | |
| 62 parameters => [qw(id)] | |
| 63 } unless ref $method; | |
| 64 | |
| 65 } else { | |
| 66 die ForbiddenException->new(); | |
| 67 } | |
| 68 | |
| 69 return $this->InvokeMember($method,$id,$action); | |
| 70 } | |
| 71 | |
| 72 sub PutImpl { | |
| 73 my ($this,$id,$action) = @_; | |
| 74 | |
| 75 my $rx = $this->childRegex; | |
| 76 if ( $rx and $id =~ m/$rx/ and $this->update ) { | |
| 77 my $method = $this->update or die ForbiddenException->new(); | |
| 78 | |
| 79 $method = { | |
| 80 method => $method, | |
| 81 parameters => [qw(id query)] | |
| 82 } unless ref $method; | |
| 83 | |
| 84 return $this->InvokeMember($method,$id,$action); | |
| 85 } else { | |
| 86 die ForbiddenException->new(); | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 sub PostImpl { | |
| 91 my ($this,$id,$action) = @_; | |
| 92 | |
| 93 my $method; | |
| 94 | |
| 95 if (length $id == 0) { | |
| 96 $method = $this->insert or die ForbiddenException->new(); | |
| 97 | |
| 98 $method = { | |
| 99 method => $method, | |
| 100 parameters => [qw(query)] | |
| 101 } unless ref $method; | |
| 102 } elsif ($method = $this->methods->{$id}) { | |
| 103 die ForbiddenException->new() unless ref $method and $method->{allowPost}; | |
| 104 } else { | |
| 105 die ForbiddenException->new(); | |
| 106 } | |
| 107 | |
| 108 return $this->InvokeMemeber($method,$id,$action); | |
| 109 } | |
| 110 | |
| 111 sub DeleteImpl { | |
| 112 my ($this,$id,$action) = @_; | |
| 113 | |
| 114 my $rx = $this->childRegex; | |
| 115 if ($rx and $id =~ m/$rx/ and my $method = $this->delete) { | |
| 116 | |
| 117 $method = { | |
| 118 method => $method, | |
| 119 parameters => [qw(id)] | |
| 120 } unless ref $method; | |
| 121 | |
| 122 return $this->InvokeMember($method,$id,$action); | |
| 123 } else { | |
| 124 die ForbiddenException->new(); | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 sub HttpFallbackImpl { | |
| 129 die ForbiddenException->new(); | |
| 130 } | |
| 131 | |
| 132 sub InvokeMember { | |
| 133 my ($this,$method,$id,$action) = @_; | |
| 134 } | |
| 135 | |
| 136 | |
| 4 1; | 137 1; |
| 5 | 138 |
| 6 __END__ | 139 __END__ |
| 7 | 140 |
| 8 =pod | 141 =pod |
| 9 | 142 |
| 10 =head1 NAME | 143 =head1 NAME |
| 11 | 144 |
| 12 C<IMPL::Web::Application::RestResource> - ресурс Rest вебсервиса. | 145 C<IMPL::Web::Application::RestResource> - ресурс Rest вебсервиса. |
| 13 | 146 |
| 147 =head1 SYNOPSIS | |
| 148 | |
| 149 =begin text | |
| 150 | |
| 151 [REQUEST] | |
| 152 GET /artists | |
| 153 | |
| 154 [RESPONSE] | |
| 155 <artists> | |
| 156 <artist id="1"> | |
| 157 <name>The Beatles <name/> | |
| 158 </atrist> | |
| 159 <artist id="2"> | |
| 160 <name>Bonobo</name> | |
| 161 </artist> | |
| 162 </artists> | |
| 163 | |
| 164 [REQUEST] | |
| 165 GET /artists/1/cds?title='Live at BBC' | |
| 166 | |
| 167 [RESPONSE] | |
| 168 <cds> | |
| 169 <cd id="14"> | |
| 170 <title>Live at BBC 1</title> | |
| 171 </cd> | |
| 172 <cd id="15"> | |
| 173 <title>Live at BBC 2</title> | |
| 174 </cd> | |
| 175 </cds> | |
| 176 | |
| 177 [REQUEST] | |
| 178 GET /cds/15 | |
| 179 | |
| 180 [RESPONSE] | |
| 181 <cd id="15"> | |
| 182 <title>Live at BBC 2</title> | |
| 183 </cd> | |
| 184 | |
| 185 =end text | |
| 186 | |
| 187 =begin code | |
| 188 | |
| 189 use IMPL::require { | |
| 190 TRes => 'IMPL::Web:Application::RestResource', | |
| 191 DataContext => 'My::App::DataContext' | |
| 192 }; | |
| 193 | |
| 194 my $cds = TRes->new( | |
| 195 DataContext->Default, | |
| 196 { | |
| 197 methods => { | |
| 198 get => { | |
| 199 | |
| 200 }, | |
| 201 post => { | |
| 202 | |
| 203 } | |
| 204 } | |
| 205 get => 'search', | |
| 206 | |
| 207 | |
| 208 } | |
| 209 ); | |
| 210 | |
| 211 =end code | |
| 212 | |
| 14 =head1 DESCRIPTION | 213 =head1 DESCRIPTION |
| 15 | 214 |
| 215 Каждый ресурс представляет собой коллекцию и реализует методы C<HTTP> C<GET,POST,PUT,DELETE>. | |
| 216 | |
| 217 =head2 HTTP METHODS | |
| 218 | |
| 219 =head3 C<GET> | |
| 220 | |
| 221 Возвращает коллекцию дочерних ресурсов. | |
| 222 | |
| 223 =head3 C<GET {id}> | |
| 224 | |
| 225 Возвращает дочерний объект с идентификатором C<id> | |
| 226 | |
| 227 =head3 C<GET {method}> | |
| 228 | |
| 229 Вызывает метод C<method> и возвращает его результаты. При публикации методов доступных | |
| 230 через C<GET> данные методы не должны вносить изменений в предметную область. | |
| 231 | |
| 232 =head3 C<PUT {id}> | |
| 233 | |
| 234 Обновляет дочерний ресурс с указанным идентификатором. | |
| 235 | |
| 236 =head3 C<DELETE {id}> | |
| 237 | |
| 238 Удаляет дочерний ресурс с указанным идентификатором. | |
| 239 | |
| 240 =head3 C<POST> | |
| 241 | |
| 242 Добавляет новый дочерний ресурс в коллекцию. | |
| 243 | |
| 244 =head2 HTTP METHOD MAPPING | |
| 245 | |
| 246 =head3 C<POST {method}> | |
| 247 | |
| 248 Вызывает метод C<method>, в отличии от C<GET> методы опубликованные через C<POST> могут вносить | |
| 249 изменения в объекты. | |
| 250 | |
| 251 =head1 MEMBERS | |
| 252 | |
| 253 =head2 C<[get]target> | |
| 254 | |
| 255 Объект (также может быть и класс), обеспечивающий функционал ресурса. | |
| 256 | |
| 257 =head2 C<[get]methods> | |
| 258 | |
| 259 =head2 C<[get]childRegex> | |
| 260 | |
| 261 =head2 C<[get]fetch> | |
| 262 | |
| 263 =head2 C<[get]list> | |
| 264 | |
| 265 =head2 C<[get]insert> | |
| 266 | |
| 267 =head2 C<[get]update> | |
| 268 | |
| 269 =head2 C<[get]delete> | |
| 270 | |
| 271 =head2 C<GetImpl($child,$action)> | |
| 272 | |
| 273 =head2 C<PutImpl($child,$action)> | |
| 274 | |
| 275 =head2 C<PostImpl($child,$action)> | |
| 276 | |
| 277 =head2 C<DeleteImpl($child,$action)> | |
| 278 | |
| 279 =head2 C<InvokeMember($memberInfo,$child,$action)> | |
| 280 | |
| 16 =cut | 281 =cut |
