File Coverage

blib/lib/Dancer/Plugin/JSON/Schema.pm
Criterion Covered Total %
statement 49 50 98.0
branch 16 20 80.0
condition 3 7 42.8
subroutine 9 9 100.0
pod n/a
total 77 86 89.5


line stmt bran cond sub pod time code
1             package Dancer::Plugin::JSON::Schema;
2              
3             our $VERSION = '0.001'; # VERSION
4              
5 3     3   854815 use strict;
  3         7  
  3         81  
6 3     3   14 use warnings;
  3         5  
  3         68  
7 3     3   2533 use utf8;
  3         30  
  3         15  
8 3     3   2257 use Dancer::Plugin;
  3         3791  
  3         204  
9 3     3   2734 use JSON ();
  3         35998  
  3         122  
10 3     3   2007 use JSON::Schema;
  3         204879  
  3         114  
11 3     3   26 use JSON::Hyper;
  3         5  
  3         72  
12 3     3   15 use Dancer qw(:syntax);
  3         6  
  3         27  
13              
14             my $schemas = {};
15              
16             sub json_schema {
17 9     9   9357 my ($self, $name) = plugin_args(@_);
18 9         49 my $cfg = plugin_setting;
19              
20 9 100       194 if (not defined $name) {
21 5 100       23 if (keys %$cfg == 1) {
    50          
22 1         3 ($name) = keys %$cfg;
23             } elsif (keys %$cfg) {
24 4         8 $name = "default";
25             } else {
26 0         0 die "No JSON Schemas are configured";
27             }
28             }
29              
30 9 100       35 return $schemas->{$name} if $schemas->{$name};
31              
32 8 100       48 my $options = $cfg->{$name} or die "The schema $name is not configured";
33              
34 6 100       23 if ( my $alias = $options->{alias} ) {
35 3 100       26 $options = $cfg->{$alias}
36             or die "The schema alias $alias does not exist in the config";
37 2 50       14 return $schemas->{$alias} if $schemas->{$alias};
38             }
39              
40             my $schema_info =
41             $options->{schema_info}
42             //
43             {
44 3   50     17 map { $_, $options->{$_} } qw(
  6         30  
45             options
46             schema
47             )
48             }
49             ;
50              
51 3 50       15 unless ( ref $schema_info->{schema} ) {
52             # get the file
53 3   33     14 my $appdir = config->{appdir} // __FILE__ =~ s~(?:/blib)?/lib/Dancer/Plugin/JSON/Schema\.pm~~r;
54 3         57 my $fn = $appdir . '/' . $schema_info->{schema};
55 3 50       154 open ( my $fh, '<', $fn ) or die ("Could not open schema file $fn for read");
56 3         7 my $raw_json = '';
57 3         1182 $raw_json .= $_ while (<$fh>);
58 3         17 my $parsed_json = JSON::from_json($raw_json);
59 3         133 JSON::Hyper->new->process_includes($parsed_json, '/', undef);
60 3         351 $schema_info->{schema} = $parsed_json;
61             }
62              
63 3         6 my $schema;
64              
65 3   50     43 $schema = JSON::Schema->new( $schema_info->{schema}, $schema_info->{options} // {} );
66              
67 3         60 return $schemas->{$name} = $schema;
68             };
69              
70             register json_schema => \&json_schema;
71              
72             register_plugin for_versions => [ 1, 2 ];
73              
74             # ABSTRACT: JSON::Schema interface for Dancer applications
75              
76              
77             1;
78              
79             __END__
80              
81             =pod
82              
83             =encoding UTF-8
84              
85             =head1 NAME
86              
87             Dancer::Plugin::JSON::Schema - JSON::Schema interface for Dancer applications
88              
89             =head1 VERSION
90              
91             version 0.001
92              
93             =head1 SYNOPSIS
94              
95             use Dancer;
96             use Dancer::Plugin::JSON::Schema qw(json_schema);
97              
98             post '/search' => sub {
99             my $structure = param('q');
100             my $result = json_schema('default')->validate($structure);
101              
102             # If you are accessing the 'default' schema, then you can just do:
103             my $result = json_schema->validate($structure);
104              
105             ...
106             };
107              
108             dance;
109              
110             =head1 DESCRIPTION
111              
112             This plugin makes it very easy to create L<Dancer> applications that interface
113             with JSON Schema.
114              
115             It automatically exports the keyword C<json_schema> which returns an L<JSON::Schema> object.
116              
117             You just need to configure where to get the schema from.
118              
119             For performance, JSON::Schema objects are cached in memory and are lazy loaded the first time they are accessed.
120              
121             =head1 CONFIGURATION
122              
123             Configuration can be done in your L<Dancer> config file.
124              
125             =head2 Simple example
126              
127             Here is a simple example. It defines one schema named C<default>:
128              
129             plugins:
130             'JSON::Schema':
131             default:
132             schema: schemas/item.json
133              
134             =head2 Multiple schemas
135              
136             In this example, there are 2 schemas configured named C<default> and C<accessories>:
137              
138             plugins:
139             'JSON::Schema':
140             default:
141             schema: schemas/item.json
142             user:
143             schema: schemas/user.json
144              
145             Each schema configured must at least have a C<schema> option set.
146              
147             If you only have one schema configured, or one of them is named
148             C<default>, you can call C<json_schema> without an argument to get the only
149             or C<default> schema, respectively.
150              
151             =head2 schema_info
152              
153             Alternatively, you may also declare your schema information inside a hash named C<schema_info>:
154              
155             plugins:
156             'JSON::Schema':
157             default:
158             schema_info:
159             schema: schemas/item.json
160              
161             =head2 alias
162              
163             Aliases allow you to reference the same underlying schema with multiple names.
164              
165             For example:
166              
167             plugins:
168             'JSON::Schema':
169             default:
170             schemas/item.json
171             products:
172             alias: default
173              
174             Now you can access the default schema with C<json_schema()>, C<json_schema('default')>,
175             or C<json_schema('products')>.
176              
177             =head1 FUNCTIONS
178              
179             =head2 json_schema
180              
181             my $result = json_schema->validate( $structure );
182              
183             The C<json_schema> keyword returns a L<JSON::Schema> object ready for you to use.
184              
185             If you have configured only one schema, then you can simply call C<json_schema> with no arguments.
186              
187             If you have configured multiple schemas, you can still call C<json_schema> with no arguments if there is a schema named C<default> in the configuration.
188              
189             With no argument, the C<default> schema is returned.
190              
191             Otherwise, you B<must> provide C<json_schema()> with the name of the schema:
192              
193             my $user = json_schema('accessories')->select( ... );
194              
195             =head1 AUTHORS AND CONTRIBUTORS
196              
197             This module is based on L<Dancer::Plugin::DBIC>, as at 22 October 2014, and adapted for JSON::Schema by Daniel Perrett.
198              
199             The following had authored L<Dancer::Plugin::DBIC> at this time:
200              
201             =over 4
202              
203             =item *
204              
205             Al Newkirk <awncorp@cpan.org>
206              
207             =item *
208              
209             Naveed Massjouni <naveed@vt.edu>
210              
211             =back
212              
213             The following had made contributions to L<Dancer::Plugin::DBIC> at this time:
214              
215             =over 4
216              
217             =item *
218              
219             Alexis Sukrieh <sukria@sukria.net>
220              
221             =item *
222              
223             Dagfinn Ilmari MannsÃ¥ker <L<https://github.com/ilmari>>
224              
225             =item *
226              
227             David Precious <davidp@preshweb.co.uk>
228              
229             =item *
230              
231             Fabrice Gabolde <L<https://github.com/fgabolde>>
232              
233             =item *
234              
235             Franck Cuny <franck@lumberjaph.net>
236              
237             =item *
238              
239             Steven Humphrey <L<https://github.com/shumphrey>>
240              
241             =item *
242              
243             Yanick Champoux <L<https://github.com/yanick>>
244              
245             =back
246              
247             =head1 AUTHORS
248              
249             =over 4
250              
251             =item *
252              
253             Daniel Perrett <dp13@sanger.ac.uk>
254              
255             =item *
256              
257             Al Newkirk <awncorp@cpan.org>
258              
259             =item *
260              
261             Naveed Massjouni <naveed@vt.edu>
262              
263             =back
264              
265             =head1 COPYRIGHT AND LICENSE
266              
267             This software is copyright (c) 2010 by awncorp.
268              
269             This is free software; you can redistribute it and/or modify it under
270             the same terms as the Perl 5 programming language system itself.
271              
272             =cut