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