1rest(n) A framework for RESTful web services rest(n)
2
3
4
5______________________________________________________________________________
6
8 rest - define REST web APIs and call them inline or asychronously
9
11 package require Tcl 8.5
12
13 package require rest ?1.5?
14
15 ::rest::simple url query ?config? ?body?
16
17 ::rest::get url query ?config? ?body?
18
19 ::rest::post url query ?config? ?body?
20
21 ::rest::patch url query ?config? ?body?
22
23 ::rest::head url query ?config? ?body?
24
25 ::rest::put url query ?config? ?body?
26
27 ::rest::delete url query ?config? ?body?
28
29 ::rest::save name file
30
31 ::rest::describe name
32
33 ::rest::parameters url ?key?
34
35 ::rest::parse_opts static required optional words
36
37 ::rest::substitute string var
38
39 ::rest::create_interface name
40
41______________________________________________________________________________
42
44 There are two types of usage this package supports: simple calls, and
45 complete interfaces. In an interface you specify a set of rules and
46 then the package builds the commands which correspond to the REST meth‐
47 ods. These commands can have many options such as input and output
48 transformations and data type specific formatting. This results in a
49 cleaner and simpler script. On the other hand, while a simple call is
50 easier and quicker to implement it is also less featureful. It takes
51 the url and a few options about the command and returns the result di‐
52 rectly. Any formatting or checking is up to rest of the script.
53
55 In simple usage you make calls using the http method procedures and
56 then check or process the returned data yourself
57
58 ::rest::simple url query ?config? ?body?
59
60 ::rest::get url query ?config? ?body?
61
62 ::rest::post url query ?config? ?body?
63
64 ::rest::patch url query ?config? ?body?
65
66 ::rest::head url query ?config? ?body?
67
68 ::rest::put url query ?config? ?body?
69
70 ::rest::delete url query ?config? ?body?
71
72 These commands are all equivalent except for the http method
73 used. If you use simple then the method should be specified as
74 an option in the config dictionary. If that is not done it de‐
75 faults to get. If a body is needed then the config dictionary
76 must be present, however it is allowed to be empty.
77
78 The config dictionary supports the following keys
79
80 auth
81
82 content-type
83
84 cookie
85
86 error-body
87
88 format
89
90 headers
91
92 method
93
94 Two quick examples:
95
96 Example 1, Yahoo Boss:
97
98
99 set appid APPID
100 set search tcl
101 set res [rest::get http://boss.yahooapis.com/ysearch/web/v1/$search [list appid $appid]]
102 set res [rest::format_json $res]
103
104
105 Example 2, Twitter:
106
107
108 set url http://twitter.com/statuses/update.json
109 set query [list status $text]
110 set res [rest::simple $url $query {
111 method post
112 auth {basic user password}
113 format json
114 }]
115
116
118 An interface to a REST API consists of a series of definitions of REST
119 calls contained in an array. The name of that array becomes a name‐
120 space containing the defined commands. Each key of the array specifies
121 the name of the call, with the associated configuration a dictionary,
122 i.e. key/value pairs. The acceptable keys, i.e. legal configuration
123 options are described below. After creating the definitions in the ar‐
124 ray simply calling rest::create_interface with the array as argument
125 will then create the desired commands.
126
127 Example, Yahoo Weather:
128
129
130 package require rest
131
132 set yweather(forecast) {
133 url http://weather.yahooapis.com/forecastrss
134 req_args { p: }
135 opt_args { u: }
136 }
137 rest::create_interface yweather
138 puts [yweather::forecast -p 94089]
139
140
141 ::rest::save name file
142 This command saves a copy of the dynamically created procedures
143 for all the API calls specified in the array variable name to
144 the file, for later loading.
145
146 The result of the command is the empty string
147
148 ::rest::describe name
149 This command prints a description of all API calls specified in
150 the array variable name to the channel stdout.
151
152 The result of the command is the empty string.
153
154 ::rest::parameters url ?key?
155 This command parses an url query string into a dictionary and
156 returns said dictionary as its result.
157
158 If key is specified the command will not return the entire dic‐
159 tionary, but only the value of that key.
160
161 ::rest::parse_opts static required optional words
162 This command implements a custom parserfor command options.
163
164 dict static
165 A dictionary of options and their values that are always
166 present in the output.
167
168 list required
169 A list of options that must be supplied by words
170
171 list optional
172 A list of options that may appear in the words, but are
173 not required. The elements must be in one of three
174 forms:
175
176 name The option may be present or not, no default.
177
178 name: When present the option requires an argument.
179
180 name:value
181 When not present use value as default.
182
183 list words
184 The words to parse into options and values.
185
186 The result of the command is a list containing two elements. The first
187 element is a dictionary containing the parsed options and their values.
188 The second element is a list of the remaining words.
189
190 ::rest::substitute string var
191 This command takes a string, substitutes values for any option
192 identifiers found inside and returns the modified string as its
193 results.
194
195 The values to substitute are found in the variable var, which is
196 expected to contain a dictionary mapping from the option identi‐
197 fiers to replace to their values. Note that option identifiers
198 which have no key in var are replaced with the empty string.
199
200 The option identifiers in string have to follow the syntax %...%
201 where ... may contain any combination of lower-case alphanumeric
202 characters, plus underscore, colon and dash.
203
204 ::rest::create_interface name
205 This command creates procedures for all the API calls specified
206 in the array variable name.
207
208 The name of that array becomes a namespace containing the de‐
209 fined commands. Each key of the array specifies the name of the
210 call, with the associated configuration a dictionary, i.e.
211 key/value pairs. The legal keys and their meanings are:
212
213 url The value of this required option must be the target of
214 the http request.
215
216 description
217 The value of this option must be a short string describ‐
218 ing the call. Default to the empty string, if not speci‐
219 fied. Used only by ::rest::describe.
220
221 body The value of this option indicates if arguments are re‐
222 quired for the call's request body or not. The acceptable
223 values are listed below. Defaults to optional if not
224 specified.
225
226 none The call has no request body, none must be sup‐
227 plied.
228
229 optional
230 A request body can be supplied, but is not re‐
231 quired.
232
233 required
234 A request body must be supplied.
235
236 argument
237 This value must be followed by the name of an op‐
238 tion, treating the entire string as a list. The
239 request body will be used as the value of that op‐
240 tion.
241
242 mime_multipart
243 A request body must be supplied and will be inter‐
244 preted as each argument representing one part of a
245 mime/multipart document. Arguments must be lists
246 containing 2 elements, a list of header keys and
247 values, and the mime part body, in this order.
248
249 mime_multipart/<value>
250 Same as mime_multipart, but the Content-Type
251 header is set to multipart/<value>.
252
253 method The value of this option must be the name of the HTTP
254 method to call on the url. Defaults to GET, if not spec‐
255 ified. The acceptable values are GET, POST, and PUT, re‐
256 gardless of letter-case.
257
258 copy When present the value of this option specifies the name
259 of a previously defined call. The definition of that call
260 is copied to the current call, except for the options
261 specified by the current call itself.
262
263 unset When present the value of this option contains a list of
264 options in the current call. These options are removed
265 from the definition. Use this after copying an existing
266 definition to remove options, instead of overriding their
267 value.
268
269 headers
270 Specification of additional header fields. The value of
271 this option must be a dictionary, interpreted to contain
272 the new header fields and their values. The default is to
273 not add any additional headers.
274
275 content-type
276 The value of this option specifies the content type for
277 the request data.
278
279 req_args
280 The value of this option is a list naming the required
281 arguments of the call. Names ending in a colon will re‐
282 quire a value.
283
284 opt_args
285 The value of this option a list naming the arguments that
286 may be present for a call but are not required.
287
288 static_args
289 The value of this option a list naming the arguments that
290 are always the same. No sense in troubling the user with
291 these. A leading dash (-) is allowed but not required to
292 maintain consistency with the command line.
293
294 auth The value of this option specifies how to authenticate
295 the calls. No authentication is done if the option is
296 not specified.
297
298 basic The user may configure the basic authentication by
299 overriding the procedure basic_auth in the name‐
300 space of interface. This procedure takes two argu‐
301 ments, the username and password, in this order.
302
303 bearer The user may configure a bearer token as authenti‐
304 cation. The value is the token passed to the HTTP
305 authorization header.
306
307 sign The value must actually be a list with the second
308 element the name of a procedure which will be
309 called to perform request signing.
310
311 callback
312 If this option is present then the method will be created
313 as an async call. Such calls will return immediately with
314 the value of the associated http token instead of the
315 call's result. The event loop must be active to use this
316 option.
317
318 The value of this option is treated as a command prefix
319 which is invoked when the HTTP call is complete. The pre‐
320 fix will receive at least two additional arguments, the
321 name of the calling procedure and the status of the re‐
322 sult (one of OK or ERROR), in this order.
323
324 In case of OK a third argument is added, the data associ‐
325 ated with the result.
326
327 If and only if the ERROR is a redirection, the location
328 redirected to will be added as argument. Further, if the
329 configuration key error-body is set to true the data as‐
330 sociated with the result will be added as argument as
331 well.
332
333 The http request header will be available in that proce‐
334 dure via upvar token token.
335
336 cookie The value of this option is a list of cookies to be
337 passed in the http header. This is a shortcut to the
338 headers option.
339
340 input_transform
341 The value of this option is a command prefix or script to
342 perform a transformation on the query before invoking the
343 call. A script transform is wrapped into an automatically
344 generated internal procedure.
345
346 If not specified no transformation is done.
347
348 The command (prefix) must accept a single argument, the
349 query (a dictionary) to transform, and must return the
350 modified query (again as dictionary) as its result. The
351 request body is accessible in the transform command via
352 upvar body body.
353
354 format
355
356 result The value of this option specifies the format of the re‐
357 turned data. Defaults to auto if not specified. The ac‐
358 ceptable values are:
359
360 auto Auto detect between xml and json.
361
362 discard
363
364 json
365
366 raw
367
368 rss This is formatted as a special case of xml.
369
370 tdom
371
372 xml
373
374 pre_transform
375 The value of this option is a command prefix or script to
376 perform a transformation on the result of a call (before
377 the application of the output transform as per format). A
378 script transform is wrapped into an automatically gener‐
379 ated internal procedure.
380
381 If not specified no transformation is done.
382
383 The command (prefix) must accept a single argument, the
384 result to transform, and must return the modified result
385 as its result.
386
387 The http request header is accessible in the transform
388 command via upvar token token
389
390 post_transform
391 The value of this option is a command prefix or script to
392 perform a transformation on the result of a call (after
393 the application of the output transform as per format). A
394 script transform is wrapped into an automatically gener‐
395 ated internal procedure.
396
397 If not specified no transformation is done.
398
399 The command (prefix) must accept a single argument, the
400 result to transform, and must return the modified result
401 as its result.
402
403 The http request header is accessible in the transform
404 command via upvar token token
405
406 check_result
407 The value of this option must be list of two expressions,
408 either of which may be empty.
409
410 The first expression is checks the OK condition, it must
411 return true when the result is satisfactory, and false
412 otherwise.
413
414 The second expression is the ERROR condition, it must re‐
415 turn false unless there is an error, then it has to re‐
416 turn true.
417
418 error_body
419 The value of this option determines whether to return the
420 response when encountering an HTTP error, or not. The de‐
421 fault is to not return the response body on error.
422
423 See callback above for more information.
424
426 Yahoo Geo:
427
428
429 set ygeo(parse) {
430 url http://wherein.yahooapis.com/v1/document
431 method post
432 body { arg documentContent }
433 }
434 ygeo::parse "san jose ca"
435 # "san jose ca" will be interpreted as if it were specified as the -documentContent option
436
437
438 Google Docs:
439
440
441 set gdocs(upload) {
442 url http://docs.google.com/feeds/default/private/full
443 body mime_multipart
444 }
445 gdocs::upload [list {Content-Type application/atom+xml} $xml] [list {Content-Type image/jpeg} $filedata]
446
447
448 Delicious:
449
450
451 set delicious(updated) {
452 url https://api.del.icio.us/v1/posts/update
453 auth basic
454 }
455
456 rest::create_interface flickr
457
458 flickr::basic_auth username password
459
460
461 Flickr:
462
463
464 set flickr(auth.getToken) {
465 url http://api.flickr.com/services/rest/
466 req_args { api_key: secret: }
467 auth { sign do_signature }
468 }
469
470 rest::create_interface flickr
471
472 proc ::flickr::do_signature {query} {
473 # perform some operations on the query here
474 return $query
475 }
476
477
479 The package provides functional but incomplete implementations for the
480 following services:
481
482 del.icio.us
483
484 facebook
485
486 flickr
487
488 twitter
489
490 google calendar
491
492 yahoo boss
493
494 yahoo weather
495
496 Please either read the package's implementation, or use rest::describe
497 after loading it for their details.
498
499 Do not forget developers' documentation on the respective sites either.
500
502 The rest package can be used with https-secured services, by requiring
503 the TLS package and then registering it with the http package it is
504 sitting on top of. Example
505
506
507 package require tls
508 http::register https 443 ::tls::socket
509
510
512 This package uses the TLS package to handle the security for https urls
513 and other socket connections.
514
515 Policy decisions like the set of protocols to support and what ciphers
516 to use are not the responsibility of TLS, nor of this package itself
517 however. Such decisions are the responsibility of whichever applica‐
518 tion is using the package, and are likely influenced by the set of
519 servers the application will talk to as well.
520
521 For example, in light of the recent POODLE attack [http://googleonli‐
522 nesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
523 ssl-30.html] discovered by Google many servers will disable support for
524 the SSLv3 protocol. To handle this change the applications using TLS
525 must be patched, and not this package, nor TLS itself. Such a patch
526 may be as simple as generally activating tls1 support, as shown in the
527 example below.
528
529
530 package require tls
531 tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol
532
533 ... your own application code ...
534
535
537 This document, and the package it describes, will undoubtedly contain
538 bugs and other problems. Please report such in the category rest of
539 the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. Please
540 also report any ideas for enhancements you may have for either package
541 and/or documentation.
542
543 When proposing code changes, please provide unified diffs, i.e the out‐
544 put of diff -u.
545
546 Note further that attachments are strongly preferred over inlined
547 patches. Attachments can be made by going to the Edit form of the
548 ticket immediately after its creation, and then using the left-most
549 button in the secondary navigation bar.
550
551
552
553tcllib 1.5 rest(n)