File Coverage

blib/lib/Plack/App/Catmandu/Bag.pm
Criterion Covered Total %
statement 55 60 91.6
branch 6 12 50.0
condition 6 10 60.0
subroutine 17 18 94.4
pod 1 10 10.0
total 85 110 77.2


line stmt bran cond sub pod time code
1             package Plack::App::Catmandu::Bag;
2              
3 1     1   356177 use Catmandu::Sane;
  1         9  
  1         8  
4              
5             our $VERSION = '0.0102';
6              
7 1     1   215 use parent 'Plack::Component';
  1         2  
  1         6  
8 1     1   3442 use Catmandu;
  1         2  
  1         6  
9 1     1   646 use Router::Simple;
  1         3925  
  1         28  
10 1     1   7 use JSON qw(encode_json);
  1         2  
  1         7  
11 1     1   101 use namespace::clean;
  1         3  
  1         7  
12              
13             sub bag {
14 8     8 0 15 my ($self) = @_;
15 8   66     112 $self->{_bag} ||= $self->_build_bag;
16             }
17              
18             sub router {
19 7     7 0 11 my ($self) = @_;
20 7   66     30 $self->{_router} ||= $self->_build_router;
21             }
22              
23             sub _build_bag {
24 1     1   16 my ($self) = @_;
25 1         9 Catmandu->store($self->{store})->bag($self->{bag});
26             }
27              
28             sub _build_router {
29 1     1   3 my ($self) = @_;
30 1         8 my $router = Router::Simple->new;
31 1 50       10 if ($self->bag->does('Catmandu::Plugin::Versioning')) {
32 1         130 $router->connect(
33             '/{id}/versions',
34             {action => 'version_list'},
35             {method => ['GET', 'HEAD']},
36             );
37 1         144 $router->connect(
38             '/{id}/versions/{version}',
39             {action => 'version_show'},
40             {method => ['GET', 'HEAD']},
41             );
42             }
43 1         94 $router->connect('/', {action => 'list'}, {method => ['GET', 'HEAD']});
44 1         66 $router->connect('/{id}', {action => 'show'},
45             {method => ['GET', 'HEAD']});
46 1         80 $router;
47             }
48              
49             sub list {
50 1     1 0 3 my ($self, $params) = @_;
51 1   50     10 my $start = $params->{start} // 0;
52 1   50     7 my $limit = $params->{limit} // 10;
53 1         4 $self->ok($self->bag->slice($start, $limit)->to_array);
54             }
55              
56             sub show {
57 2     2 0 5 my ($self, $params) = @_;
58 2 100       6 if (my $data = $self->bag->get($params->{id})) {
59 1         92 $self->ok($data);
60             }
61             else {
62 1         66 $self->not_found;
63             }
64             }
65              
66             sub version_list {
67 2     2 0 4 my ($self, $params) = @_;
68 2 50       7 if (my $data = $self->bag->get_history($params->{id})) {
69 2         896 $self->ok($data);
70             }
71             else {
72 0         0 $self->not_found;
73             }
74             }
75              
76             sub version_show {
77 2     2 0 4 my ($self, $params) = @_;
78 2 50       5 if (my $data = $self->bag->get_version($params->{id}, $params->{version}))
79             {
80 2         496 $self->ok($data);
81             }
82             else {
83 0         0 $self->not_found;
84             }
85             }
86              
87             sub ok {
88 6     6 0 144 my ($self, $data) = @_;
89 6         13 my $res = {data => $data};
90             [
91 6         111 '200', ['Content-Type' => 'application/vnd.api+json'],
92             [encode_json($res)],
93             ];
94             }
95              
96             sub method_not_allowed {
97 0     0 0 0 ['405', ['Content-Type' => 'text/plain'], ['Method Not Allowed']];
98             }
99              
100             sub not_found {
101 1     1 0 10 ['404', ['Content-Type' => 'text/plain'], ['Not Found']];
102             }
103              
104             sub call {
105 7     7 1 174720 my ($self, $env) = @_;
106 7         19 my $router = $self->router;
107              
108 7 50       23 if (my $params = $router->match($env)) {
    0          
109 7         541 my $action = $params->{action};
110 7         27 $self->$action($params);
111             }
112             elsif ($router->method_not_allowed) {
113 0           $self->method_not_allowed;
114             }
115             else {
116 0           $self->not_found;
117             }
118             }
119              
120             1;
121              
122             __END__
123              
124             =encoding utf-8
125              
126             =head1 NAME
127              
128             Plack::App::Catmandu::Bag - Wrap a REST API around a Catmandu::Bag
129              
130             =head1 SYNOPSIS
131              
132             use Catmandu;
133             use Plack::Builder;
134             use Plack::App::Catmandu::Bag;
135              
136             Catmandu->define_store('library',
137             MongoDB => (bags => {books => {plugins => ['Versioning']}}));
138              
139             builder {
140             mount '/api/books' => Plack::App::Catmandu::Bag->new(
141             store => 'library',
142             bag => 'books',
143             );
144             };
145              
146             =head1 DESCRIPTION
147              
148             This is an early minimal release, look at the tests for usage.
149              
150             =head1 AUTHOR
151              
152             Nicolas Steenlant E<lt>nicolas.steenlant@ugent.beE<gt>
153              
154             =head1 COPYRIGHT
155              
156             Copyright 2017- Nicolas Steenlant
157              
158             =head1 LICENSE
159              
160             This library is free software; you can redistribute it and/or modify
161             it under the same terms as Perl itself.
162              
163             =head1 SEE ALSO
164              
165             =cut