forked from Jayceh/Respite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.html
342 lines (247 loc) · 11.6 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
<html><head><title>Respite::Base</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
</head>
<body class='pod'>
<!--
generated by Pod::Simple::HTML v3.28,
using Pod::Simple::PullParser v3.28,
under Perl v5.018002 at Thu Dec 17 22:21:16 2015 GMT.
If you want to change this HTML document, you probably shouldn't do that
by changing it directly. Instead, see about changing the calling options
to Pod::Simple::HTML, and/or subclassing Pod::Simple::HTML,
then reconverting this document from the Pod source.
When in doubt, email the author of Pod::Simple::HTML for advice.
See 'perldoc Pod::Simple::HTML' for more info.
-->
<!-- start doc -->
<a name='___top' class='dummyTopAnchor' ></a>
<h1><a class='u'
name="NAME"
>NAME</a></h1>
<p>Respite::Base - base class for Respite related modules that can be used from a server or commandline</p>
<h1><a class='u'
name="SYNOPSIS"
>SYNOPSIS</a></h1>
<pre> package Foo;
use base qw(Respite::Base);
my $meta = {lib_dirs => 1, dispatch_type => 'cache'};
sub api_meta { $meta }
package Foo::Bar;
sub somecall__meta { {desc => 'A method'} }
sub somecall {
my ($self, $args) = @_;
return {foo => 1};
}
my $f = Foo->new;
my $data = $f->bar_somecall;
#-----------------#
package Foo;
use strict;
use warnings;
use base qw(Respite::Base);
# sub api_meta { {} } # optional configuration
sub api_meta {
return shift->{'api_meta'} ||= { # vtable cached here
methods => {
foo => 'bar', # alias a method
baz => sub { }, # custom
},
namespaces => {
foo_child => 1,
bar_child => 1,
},
lib_dirs => {
$dir => 1, # load all .pm files as namespaces
},
};
}
sub foo__meta { {} }
sub foo {
my ($self, $args) = @_;
$self->validate_args($args);
return {...};
}
my $obj = Foo->new;
$obj->run_method("foo", $args);
# will do logging and utf8 munging - used by Respite::Server or Respite::CommandLine
$obj->foo($args); # no logging or utf8 munging
###----------------------------------------------------------------###
use Respite::Base;
my $obj = Respite::Base->new({
api_meta => {
methods => {
foo => 'bar',
},
namespaces => {
Foo => {},
},
},
});</pre>
<h1><a class='u'
name="Respite_META"
>Respite_META</a></h1>
<p>The module can specify a api_meta override, or a api_meta hashref can be passed to Respite::Base->new. The following keys are honored from api_meta.</p>
<dl>
<dt><a name="methods"
>methods</a></dt>
<dd>
<p>Can be a hard coded list of supported methods.</p>
<pre> methods => {
foo => 'bar',
fii => sub { return {data => 'some data'} },
},</pre>
<dt><a name="namespaces"
>namespaces</a></dt>
<dd>
<p>Hard coded list of method namespaces that will be used to map methods to packages spaces.</p>
<pre> namespaces => {
customer => '__',
package => '__',
},</pre>
<p>A module name will be generated from the namespace. The the methods reside in a different location, it is possible to pass along the package.</p>
<pre> namespaces => {
customer => {
match => '__',
package => 'SomeSpace::Customer',
},
},</pre>
<p>Methods are looked for in this namespace package space. Method names used in the api must either begin with a __ (__foo_method), and/or they must have a corresponding __meta entry (foo_method__meta). This allows for non-Respite methods to remain non-Respite easily. Additionally you can use the restrict method call to narrow this down even farther.</p>
<dt><a name="lib_dirs"
>lib_dirs</a></dt>
<dd>
<p>Dynamic directory of method namespaces. Items in lib_dirs will be used for a path search that will populate a namespace entry.</p>
<pre> lib_dirs => {
"$config::config{'rootdir_server'}/api_lib" => 1,
},</pre>
<p>Depending upon the path chosen, it may be necessary to supply a pkg_prefix.</p>
<pre> lib_dirs => {
"$config::config{'rootdir_server'}/lib/YAR" => {
pkg_prefix => 'YAR',
},
},</pre>
<p>Alternately, it is possible to set lib_dirs equal to "1" which will make it automatically follow the previous behavior. Note though that additional looked up modules must be found relative to the location of the parent module (@INC is not used).</p>
<dt><a name="utf8_encoded"
>utf8_encoded</a></dt>
<dd>
<p>Default false. When false, data passed should be properly utf8 decoded (or have no utf8 data at all). When true, data passed is assumed to be utf8 encoded meaning that it will need to be decoded before calling json->encode.</p>
<p>Additionally, the true value can be a hashref of methods that need this treatment. This is useful if you know some of your methods have utf8 data, while others do not.</p>
<p>(Note: Conversely when the non-json transport is finalized, it will need to call decode_utf8 to make sure data is ready for the transport.)</p>
<dt><a name="dispatch_type"
>dispatch_type</a></dt>
<dd>
<p>Can be one of new, cache, or morph. Default is new. When "new" is selected, a new object will be created with each dispatch call and it will contain a reference to the parent in the key named "base". When "cache" is selected, a cached object will be used - the object is cached inside of the base object. When "morph is selected, rather than creating a new object, the base object is temporarily blessed into the new object class.</p>
<dt><a name="enforce_requires_admin"
>enforce_requires_admin</a></dt>
<dd>
<p>Default false. If true, then validate_args will honor the requires_admin by calling require_admin if it appears in the __meta for the method.</p>
<dt><a name="allow_nested"
>allow_nested</a></dt>
<dd>
<p>Allow for nested package inheritance. The nested namespace package must provide its own api_meta.</p>
</dd>
</dl>
<h1><a class='u'
name="METHOD_NAME_RESOLUTION"
>METHOD NAME RESOLUTION</a></h1>
<p>TODO - document how we go from an Respite method name to its corresponding location.</p>
<p>Talk about builtins, methods overrides, namespaces, lib_dirs, and the __ prefix and __meta suffix.</p>
<h1><a class='u'
name="METHODS"
>METHODS</a></h1>
<p>This is an outdated list from the _Respite.pm import.</p>
<dl>
<dt><a name="base"
>base</a></dt>
<dd>
<p>When dispatch_type is set to <code>new</code> or <code>cache</code>, this method will provide access to the parent dispatching to the sub namespace.</p>
<dt><a name="base_class"
>base_class</a></dt>
<dd>
<p>If a child namespace is used directly, base_class will be looked at when the <code>base</code> method is called to create a parent base object.</p>
<dt><a name="validate_args"
>validate_args</a></dt>
<dd>
<p>See <a href="http://search.cpan.org/perldoc?Respite%3A%3AValidate" class="podlinkpod"
>Respite::Validate</a></p>
<dt><a name="verify_admin"
>verify_admin</a></dt>
<dd>
<p>Uses Respite::Client to call the emp_auth service and verify a passed in token.</p>
<dt><a name="api_preload"
>api_preload</a></dt>
<dd>
<p>Called from Respite::Server when a server is being started. This method can be used to pre load all necessary modules to avoid a penalty later on. Note that any overrides should likely call ->SUPER::api_preload as well.</p>
</dd>
</dl>
<p>The following methods are normally set when called from Respite::Server or Respite::CommandLine. If Respite::Base is used outside of these mediums, then the corresponding $self->{'propertyname'} values must be set during initialization in order to use these methods. If namespaces are used, the child class will typically fail back and look at the ->base->method value if necessary.</p>
<dl>
<dt><a name="remote_ip"
>remote_ip</a></dt>
<dd>
<p>The IP on the client machine calling this service. This is advisory. Respite::Client will use cmdline for this value when called through Respite::CommandLine on the remote box.</p>
<dt><a name="remote_user"
>remote_user</a></dt>
<dd>
<p>The user on the client machine calling this service. This is advisory.</p>
<dt><a name="transport"
>transport</a></dt>
<dd>
<p>Defaults to ''. From Respite::Server it defaults to <code>json</code> (Respite), <code>form</code> (Post variables), and <code>form-doc</code> (autodoc interface). From Respite::CommandLine it defaults to <code>cmdline</code>. It is normal in web interfaces that this value should be set to <code>gui</code>.</p>
<dt><a name="api_ip"
>api_ip</a></dt>
<dd>
<p>The IP used to talk to the service when used as an Respite server. It will be cmdline when called from Respite::CommandLine.</p>
<dt><a name="api_brand"
>api_brand</a></dt>
<dd>
<p>The brand used during api communication. As a special case, if <code>is_local</code> is true, the $ENV{'PROV'} value can be used to specify the brand.</p>
<dt><a name="admin_user"
>admin_user</a></dt>
<dd>
<p>The authenticated administrative username. Will only be set if require_admin has been called. Dies is not set.</p>
<dt><a name="is_server"
>is_server</a></dt>
<dd>
<p>Set by Respite::CommandLine and Respite::Server.</p>
<dt><a name="is_local"
>is_local</a></dt>
<dd>
<p>Only true if transport is cmdline or gui. Essentially this is a "non-api" check.</p>
<dt><a name="is_authed"
>is_authed</a></dt>
<dd>
<p>True if admin_user is set. False if not (does not die).</p>
<dt><a name="employee"
>employee</a></dt>
<dd>
<p>Will return an Employee object based on admin_user.</p>
</dd>
</dl>
<h1><a class='u'
name="RESPONSE"
>RESPONSE</a></h1>
<p>Responses from called methods should typically be hashrefs of data. These responses will be encoded by the appropriate system. Typically the encoding will be json (during Respite::Server), but possibly other forms (Perl, JSON, YAML, CSV) such as during Respite::CommandLine.</p>
<p>Methods can also return psgi style responses though this is typically more rare. (It allows for other encodings or page displays).</p>
<p>When a hashref is returned the following keys may also be returned to give additional information to the transport layer:</p>
<dl>
<dt><a name="_utf8_encoded"
>_utf8_encoded</a></dt>
<dd>
<p>This flag signals that the data is already utf8 encoded meaning that if a JSON transport layer is used, the data will need to be first decoded before being passed to JSON->encode to avoid double encoding. Typically, this should be done by setting utf8_encoded in api_meta - though the _utf8_encoded flag allows for one-off operations.</p>
<dt><a name="_extra_headers"
>_extra_headers</a></dt>
<dd>
<p>This should be an arrayref of arrayrefs containing key/val pairs. When used under Respite::Server, these will be sent as additional http headers. When using Respite::Client, the headers can be seen in the 'headers' property of a response object (non-flat).</p>
<pre> sub __some_method {
return {
_extra_headers => [
['Set-Cookie' => 'foo=bar'],
['X-Some-Header' => 'someval'],
],
normal_data_key => 'val',
};
}</pre>
</dd>
</dl>
<!-- end doc -->
</body></html>