restapi 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +83 -64
  3. data/README.rdoc +375 -2
  4. data/app/controllers/restapi/restapis_controller.rb +21 -3
  5. data/app/helpers/restapi/restapis_helper.rb +31 -0
  6. data/app/public/restapi/javascripts/bundled/prettify.js +28 -0
  7. data/app/public/restapi/javascripts/restapi.js +4 -13
  8. data/app/public/restapi/stylesheets/bundled/prettify.css +30 -0
  9. data/app/views/layouts/restapi/restapi.html.erb +36 -0
  10. data/app/views/restapi/restapis/index.html.erb +35 -33
  11. data/app/views/restapi/restapis/method.html.erb +59 -0
  12. data/app/views/restapi/restapis/resource.html.erb +71 -0
  13. data/app/views/restapi/restapis/static.html.erb +103 -0
  14. data/lib/restapi.rb +0 -10
  15. data/lib/restapi/application.rb +25 -10
  16. data/lib/restapi/dsl_definition.rb +38 -32
  17. data/lib/restapi/markup.rb +12 -12
  18. data/lib/restapi/method_description.rb +10 -8
  19. data/lib/restapi/param_description.rb +23 -10
  20. data/lib/restapi/resource_description.rb +1 -1
  21. data/lib/restapi/restapi_module.rb +15 -0
  22. data/lib/restapi/validator.rb +37 -14
  23. data/lib/restapi/version.rb +1 -1
  24. data/lib/tasks/restapi.rake +157 -0
  25. data/restapi.gemspec +1 -1
  26. data/spec/controllers/restapis_controller_spec.rb +84 -0
  27. data/spec/controllers/users_controller_spec.rb +273 -221
  28. data/spec/dummy/app/controllers/twitter_example_controller.rb +209 -208
  29. data/spec/dummy/app/controllers/users_controller.rb +23 -33
  30. data/spec/dummy/config/initializers/restapi.rb +45 -23
  31. data/spec/dummy/config/routes.rb +12 -7
  32. metadata +26 -15
  33. data/app/public/restapi/javascripts/bundled/backbone.js +0 -1431
  34. data/app/public/restapi/javascripts/bundled/json2.js +0 -487
  35. data/app/public/restapi/javascripts/bundled/underscore.js +0 -999
  36. data/app/public/restapi/javascripts/jst.js +0 -127
  37. data/app/public/restapi/javascripts/routers/documentation_router.js +0 -52
  38. data/app/public/restapi/stylesheets/bundled/bootstrap-responsive.css +0 -686
  39. data/app/public/restapi/stylesheets/bundled/bootstrap.css +0 -3990
  40. data/spec/dummy/app/controllers/dogs_controller.rb +0 -20
  41. data/spec/dummy/app/helpers/application_helper.rb +0 -2
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rails", "3.0.11"
3
+ gem "rails", ">= 3.0.11"
4
4
  gem "sqlite3"
5
5
 
6
6
  group :development, :test do
@@ -9,4 +9,5 @@ group :development, :test do
9
9
  gem "redcarpet"
10
10
  gem "RedCloth"
11
11
  gem "rake"
12
+ gem "weary", ">= 1.0.1"
12
13
  end
@@ -2,97 +2,116 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  RedCloth (4.2.9)
5
- abstract (1.0.0)
6
- actionmailer (3.0.11)
7
- actionpack (= 3.0.11)
8
- mail (~> 2.2.19)
9
- actionpack (3.0.11)
10
- activemodel (= 3.0.11)
11
- activesupport (= 3.0.11)
12
- builder (~> 2.1.2)
13
- erubis (~> 2.6.6)
14
- i18n (~> 0.5.0)
15
- rack (~> 1.2.1)
16
- rack-mount (~> 0.6.14)
17
- rack-test (~> 0.5.7)
18
- tzinfo (~> 0.3.23)
19
- activemodel (3.0.11)
20
- activesupport (= 3.0.11)
21
- builder (~> 2.1.2)
22
- i18n (~> 0.5.0)
23
- activerecord (3.0.11)
24
- activemodel (= 3.0.11)
25
- activesupport (= 3.0.11)
26
- arel (~> 2.0.10)
27
- tzinfo (~> 0.3.23)
28
- activeresource (3.0.11)
29
- activemodel (= 3.0.11)
30
- activesupport (= 3.0.11)
31
- activesupport (3.0.11)
32
- arel (2.0.10)
33
- builder (2.1.2)
5
+ actionmailer (3.2.3)
6
+ actionpack (= 3.2.3)
7
+ mail (~> 2.4.4)
8
+ actionpack (3.2.3)
9
+ activemodel (= 3.2.3)
10
+ activesupport (= 3.2.3)
11
+ builder (~> 3.0.0)
12
+ erubis (~> 2.7.0)
13
+ journey (~> 1.0.1)
14
+ rack (~> 1.4.0)
15
+ rack-cache (~> 1.2)
16
+ rack-test (~> 0.6.1)
17
+ sprockets (~> 2.1.2)
18
+ activemodel (3.2.3)
19
+ activesupport (= 3.2.3)
20
+ builder (~> 3.0.0)
21
+ activerecord (3.2.3)
22
+ activemodel (= 3.2.3)
23
+ activesupport (= 3.2.3)
24
+ arel (~> 3.0.2)
25
+ tzinfo (~> 0.3.29)
26
+ activeresource (3.2.3)
27
+ activemodel (= 3.2.3)
28
+ activesupport (= 3.2.3)
29
+ activesupport (3.2.3)
30
+ i18n (~> 0.6)
31
+ multi_json (~> 1.0)
32
+ addressable (2.2.8)
33
+ arel (3.0.2)
34
+ builder (3.0.0)
34
35
  diff-lcs (1.1.3)
35
- erubis (2.6.6)
36
- abstract (>= 1.0.0)
37
- i18n (0.5.0)
38
- json (1.6.5)
39
- mail (2.2.19)
40
- activesupport (>= 2.3.6)
36
+ erubis (2.7.0)
37
+ hike (1.2.1)
38
+ i18n (0.6.0)
39
+ journey (1.0.3)
40
+ json (1.7.3)
41
+ mail (2.4.4)
41
42
  i18n (>= 0.4.0)
42
43
  mime-types (~> 1.16)
43
44
  treetop (~> 1.4.8)
44
- mime-types (1.17.2)
45
+ mime-types (1.18)
46
+ multi_json (1.2.0)
45
47
  polyglot (0.3.3)
46
- rack (1.2.5)
47
- rack-mount (0.6.14)
48
- rack (>= 1.0.0)
49
- rack-test (0.5.7)
48
+ promise (0.3.0)
49
+ rack (1.4.1)
50
+ rack-cache (1.2)
51
+ rack (>= 0.4)
52
+ rack-ssl (1.3.2)
53
+ rack
54
+ rack-test (0.6.1)
50
55
  rack (>= 1.0)
51
- rails (3.0.11)
52
- actionmailer (= 3.0.11)
53
- actionpack (= 3.0.11)
54
- activerecord (= 3.0.11)
55
- activeresource (= 3.0.11)
56
- activesupport (= 3.0.11)
56
+ rails (3.2.3)
57
+ actionmailer (= 3.2.3)
58
+ actionpack (= 3.2.3)
59
+ activerecord (= 3.2.3)
60
+ activeresource (= 3.2.3)
61
+ activesupport (= 3.2.3)
57
62
  bundler (~> 1.0)
58
- railties (= 3.0.11)
59
- railties (3.0.11)
60
- actionpack (= 3.0.11)
61
- activesupport (= 3.0.11)
63
+ railties (= 3.2.3)
64
+ railties (3.2.3)
65
+ actionpack (= 3.2.3)
66
+ activesupport (= 3.2.3)
67
+ rack-ssl (~> 1.3.2)
62
68
  rake (>= 0.8.7)
63
69
  rdoc (~> 3.4)
64
- thor (~> 0.14.4)
70
+ thor (~> 0.14.6)
65
71
  rake (0.9.2.2)
66
72
  rdoc (3.12)
67
73
  json (~> 1.4)
68
74
  redcarpet (2.1.1)
69
- rspec (2.8.0)
70
- rspec-core (~> 2.8.0)
71
- rspec-expectations (~> 2.8.0)
72
- rspec-mocks (~> 2.8.0)
73
- rspec-core (2.8.0)
74
- rspec-expectations (2.8.0)
75
- diff-lcs (~> 1.1.2)
76
- rspec-mocks (2.8.0)
77
- rspec-rails (2.8.1)
75
+ rspec (2.10.0)
76
+ rspec-core (~> 2.10.0)
77
+ rspec-expectations (~> 2.10.0)
78
+ rspec-mocks (~> 2.10.0)
79
+ rspec-core (2.10.0)
80
+ rspec-expectations (2.10.0)
81
+ diff-lcs (~> 1.1.3)
82
+ rspec-mocks (2.10.1)
83
+ rspec-rails (2.10.1)
78
84
  actionpack (>= 3.0)
79
85
  activesupport (>= 3.0)
80
86
  railties (>= 3.0)
81
- rspec (~> 2.8.0)
82
- sqlite3 (1.3.5)
87
+ rspec (~> 2.10.0)
88
+ simple_oauth (0.1.8)
89
+ sprockets (2.1.3)
90
+ hike (~> 1.2)
91
+ rack (~> 1.0)
92
+ tilt (~> 1.1, != 1.3.0)
93
+ sqlite3 (1.3.6)
83
94
  thor (0.14.6)
95
+ tilt (1.3.3)
84
96
  treetop (1.4.10)
85
97
  polyglot
86
98
  polyglot (>= 0.3.1)
87
- tzinfo (0.3.31)
99
+ tzinfo (0.3.33)
100
+ weary (1.0.1)
101
+ addressable (~> 2.2.7)
102
+ multi_json (~> 1.2.0)
103
+ promise (~> 0.3.0)
104
+ rack (~> 1.4.0)
105
+ simple_oauth (~> 0.1.5)
88
106
 
89
107
  PLATFORMS
90
108
  ruby
91
109
 
92
110
  DEPENDENCIES
93
111
  RedCloth
94
- rails (= 3.0.11)
112
+ rails (>= 3.0.11)
95
113
  rake
96
114
  redcarpet
97
115
  rspec-rails
98
116
  sqlite3
117
+ weary (>= 1.0.1)
@@ -1,3 +1,376 @@
1
- = Rails API documentation generator
1
+ = API Documentation Tool {<img src="https://secure.travis-ci.org/Pajk/rails-restapi.png?branch=master" alt="Build Status" />}[http://travis-ci.org/Pajk/rails-restapi]
2
+
3
+ == What?
4
+
5
+ Every API needs a documentation otherwise no one know how to use it.
6
+ It is not easy to maintain such documentation always up to date if it
7
+ develops over time. Additionaly to this most programmers don't like writing
8
+ documentation and so it could happen that your API is useless because
9
+ of outdated documentation. If the documentation is just text completely
10
+ separated from code then there is no simple way to verify its correctness.
11
+
12
+ This gem adds some new methods to Rails controllers that can be used
13
+ to describe resources which are exposed by our API. It is meant to
14
+ be used for {RESTful}[http://cs.wikipedia.org/wiki/Representational_State_Transfer]
15
+ web services and because we are talking about Rails you probably know
16
+ what it is all about.
17
+
18
+ Informations you entered with provided DSL are used to generate
19
+ online documentation and validate values of incoming requests parameters.
20
+
21
+ Warning: The name rails-restapi is not final and will be changed
22
+ in near future.
23
+
24
+ == Why?
25
+
26
+ Documentation will be closer to your code and thus less prone to become
27
+ obsolete. You get documentation frontend without effort. And if you want your
28
+ own design you can do it anytime because json API for your API documentation
29
+ is provided. There are no limits on how to use those informations, the
30
+ builtin web interface is only one of possible options.
31
+
32
+ Request parameters will be validated before they will get in touch with yours
33
+ controller action or model code. And you inform API users about expected
34
+ parameters values. This information will be always actual because otherwise
35
+ your tests fail (of course you have tests!).
36
+
37
+ This is how the web interface look like. Try it live on
38
+ http://restapi-likes.rhcloud.com. Example users resource
39
+ description are taken from Twitter(c) API.
40
+
41
+ https://img.skitch.com/20120428-nruk3e87xs2cu4ydsjujdh11fq.png
42
+
43
+ https://img.skitch.com/20120428-bni2cmq5cyhjuw1jkd78e3qjxn.png
44
+
45
+ == How?
46
+
47
+ === Gemfile
48
+
49
+ Add +restapi+ gem to your gemfile and run bundle.
50
+
51
+ gem 'restapi'
52
+
53
+ For bleeding edge version use GitHub version
54
+
55
+ gem 'restapi', :git => 'git://github.com/Pajk/rails-restapi.git'
56
+
57
+ === Config file
58
+
59
+ Create configuration file in e.g. */config/initializers/restapi.rb*.
60
+ You can set application name, footer text, API and documentation base URL
61
+ and turn off validations. You can also choose your favorite markup language
62
+ of full descriptions.
63
+
64
+ [app_name] Name of your application used in breadcrumbs navigation.
65
+ [copyright] Copyright information (shown in page footer).
66
+ [doc_base_url] Documentation frontend base url.
67
+ [api_base_url] Base url of your API, most probably /api.
68
+ [validate] Parameters validation is turned off when set to false.
69
+ [app_info] Application long description.
70
+ [reload_controllers] Set to enable/disable reloading controllers (and the documentation with it), by default enabled in development.
71
+ [api_controllers_matcher] For reloading to work properly you need to specify where your API controllers are.
72
+ [markup] You can choose markup language for descriptions of your application,
73
+ resources and methods. RDoc is the default but you can choose from
74
+ Restapi::Markup::Markdown.new or Restapi::Markup::Textile.new.
75
+ In order to use Markdown you need Redcarpet gem and for Textile you
76
+ need RedCloth. Add those to your gemfile and run bundle if you
77
+ want to use them. You can also add any other markup language
78
+ processor.
79
+
80
+ Example:
81
+
82
+ Restapi.configure do |config|
83
+ config.app_name = "Test app"
84
+ config.copyright = "&copy; 2012 Pavel Pokorny"
85
+ config.doc_base_url = "/apidoc"
86
+ config.api_base_url = "/api"
87
+ config.validate = false
88
+ config.markup = Restapi::Markup::Markdown.new
89
+ config.reload_controllers = true
90
+ config.api_controllers_matcher = File.join(Rails.root, "app", "controllers", "**","*.rb")
91
+ config.app_info < <-DOC
92
+ This is where you can inform user about your application and API
93
+ in general.
94
+ DOC
95
+ end
96
+
97
+ === Routes
98
+
99
+ Add +restapi+ to your *routes.rb*, that's all.
100
+
101
+
102
+ === Resource Description
103
+
104
+ Resource can be described in corresponding controller by calling +resource_description+ method with block. Parameters described here are used
105
+ for every method unless they are overridden with NilValidator.
106
+ Parameters are inherited in controller hierarchy. So for example you can define
107
+ in base ApplicationController parameters for authentication and they will
108
+ be checked in every request.
109
+
110
+ [name] You can force resource to display under some alias.
111
+ [short] One line short description.
112
+ [path] Relative URL path of this resource.
113
+ [version] Version of this resource API, use arbitrary string.
114
+ [param] The very same parameter description as you will use method
115
+ description. Generally use this for parameters that apply
116
+ to every method in the controller (such as :user hash).
117
+ It is possible to hide it for individual methods by setting
118
+ it's validator to nil.
119
+ [description] The full multiline description of the resource and
120
+ yours API options
121
+
122
+ Example:
123
+
124
+ class UsersController < ApplicationController
125
+
126
+ resource_description do
127
+ name 'Members'
128
+ short 'Site members'
129
+ path '/users'
130
+ version '1.0 - 3.4.2012'
131
+ param :id, Fixnum, :desc => "User ID", :required => false
132
+ param :user, Hash, :desc => 'Param description for all methods' do
133
+ param :username, String, :required => true,
134
+ :desc => "Username for login"
135
+ param :password, String, :required => true,
136
+ :desc => "Password for login"
137
+ end
138
+ description < <-DOC
139
+ Full description of this resource.
140
+ DOC
141
+ end
142
+ #...
143
+ end
144
+
145
+
146
+ === Method Description
147
+
148
+ Then describe methods available to your API.
149
+
150
+ [api] Say how is this method exposed and provide short description.
151
+ The first parameter is HTTP method (one of :GET/:POST/:PUT/:DELETE).
152
+ The second parameter is relative URL path which is mapped to this
153
+ method. The last parameter is methods short description.
154
+ You can use this +api+ method more than once for one method. It could
155
+ be useful when there are more routes mapped to it.
156
+ [param] Look at Parameter description section for details.
157
+ [error] Describe each possible error that can happend what calling this
158
+ method. HTTP response code and description can be provided.
159
+ [description] Full method description which will be converted to HTML by
160
+ choosen markup language processor.
161
+ [example] Provide example of server response, whole communication or response type.
162
+ It will be formatted as code.
163
+
164
+ Example:
165
+
166
+ api :GET, "/users/:id", "Show user profile"
167
+ error :code => 401, :desc => "Unauthorized"
168
+ error :code => 404, :desc => "Not Found"
169
+ param :session, String, :desc => "user is logged in", :required => true
170
+ param :regexp_param, /^[0-9]* years/, :desc => "regexp param"
171
+ param :array_param, [100, "one", "two", 1, 2], :desc => "array validator"
172
+ param :boolean_param, [true, false], :desc => "array validator with boolean"
173
+ param :proc_param, lambda { |val|
174
+ val == "param value" ? true : "The only good value is 'param value'."
175
+ }, :desc => "proc validator"
176
+ description "method description"
177
+ example " 'user': {...} "
178
+ def show
179
+ #...
180
+ end
181
+
182
+ == Parameter Description
183
+
184
+ Use +param+ to describe every possible parameter. You can use Hash validator
185
+ in cooperation with block given to param method to describe nested parameters.
186
+
187
+ [name] The first argument is parameter name as a symbol.
188
+ [validator] Second parameter is parameter validator, choose one from section
189
+ Validators.
190
+ [desc] Parameter description.
191
+ [required] Set this true/false to make it required/optional.
192
+ Default is optional
193
+
194
+ Example:
195
+
196
+ param :user, Hash, :desc => "User info" do
197
+ param :username, String, :desc => "Username for login", :required => true
198
+ param :password, String, :desc => "Password for login", :required => true
199
+ param :membership, ["standard","premium"], :desc => "User membership"
200
+ end
201
+ def create
202
+ #...
203
+ end
204
+
205
+
206
+ == Validators
207
+
208
+ Every parameter needs to have associated validator. For now there are some
209
+ basic validators. You can always provide your own to reach complex
210
+ results.
211
+ If validations are enabled (default state) the parameters of every
212
+ request are validated. If the value is wrong a +ArgumentError+ exception
213
+ is raised and can be rescued and processed. It contains some description
214
+ of parameter value expectations. Validations can be turned off
215
+ in configuration file.
216
+
217
+ === TypeValidator
218
+
219
+ Check the parameter type. Only String, Hash and Array are supported
220
+ for the sake of simplicity. Read more to to find out how to add
221
+ your own validator.
222
+
223
+ param :session, String, :desc => "user is logged in", :required => true
224
+ param :facts, Hash, :desc => "Additional optional facts about the user"
225
+
226
+ === RegexpValidator
227
+
228
+ Check parameter value against given regular expression.
229
+
230
+ param :regexp_param, /^[0-9]* years/, :desc => "regexp param"
231
+
232
+ === ArrayValidator
233
+
234
+ Check if parameter value is included given array.
235
+
236
+ param :array_param, [100, "one", "two", 1, 2], :desc => "array validator"
237
+
238
+ === ProcValidator
239
+
240
+ If you need more complex validation and you know you won't reuse it you
241
+ can use Proc/lambda validator. Provide your own Proc taking value
242
+ of parameter as the only argument. Return true if value pass validation
243
+ or return some text about what is wrong. _Don't use the keyword *return*
244
+ if you provide instance of Proc (with lambda it is ok), just use the last
245
+ statement return property of ruby_.
246
+
247
+ param :proc_param, lambda { |val|
248
+ val == "param value" ? true : "The only good value is 'param value'."
249
+ }, :desc => "proc validator"
250
+
251
+ === HashValidator
252
+
253
+ You can describe hash parameters in depth if you provide a block with
254
+ description of nested values.
255
+
256
+ param :user, Hash, :desc => "User info" do
257
+ param :username, String, :desc => "Username for login", :required => true
258
+ param :password, String, :desc => "Password for login", :required => true
259
+ param :membership, ["standard","premium"], :desc => "User membership"
260
+ end
261
+
262
+ === NilValidator
263
+
264
+ In fact there is any NilValidator but setting it to nil can be used to
265
+ override parameters described on resource level.
266
+
267
+ Example:
268
+
269
+ param :user, nil
270
+ def destroy
271
+ #...
272
+ end
273
+
274
+ === Adding custom validator
275
+
276
+ Only basic validators are included but it is really easy to add your own.
277
+ Create new initializer with subclass of Restapi::Validator::BaseValidator.
278
+ Two methods are required to implement - instance method
279
+ <tt>validate(value)</tt> and class method
280
+ <tt>build(param_description, argument, options, block)</tt>.
281
+
282
+ When searching for validator +build+ method of every subclass of
283
+ Restapi::Validator::BaseValidator is called. The first one whitch return
284
+ constructed validator object is used.
285
+
286
+ Example: Adding IntegerValidator
287
+
288
+ We want to check if parameter value is an integer like this:
289
+
290
+ param :id, Integer, :desc => "Company ID"
291
+
292
+ So we create restapi_validators.rb initializer with this content:
293
+
294
+ class IntegerValidator < Restapi::Validator::BaseValidator
295
+
296
+ def initialize(param_description, argument)
297
+ super(param_description)
298
+ @type = argument
299
+ end
300
+
301
+ def validate(value)
302
+ return false if value.nil?
303
+ !!(value.to_s =~ \/^[-+]?[0-9]+$/)
304
+ end
305
+
306
+ def self.build(param_description, argument, options, block)
307
+ if argument == Integer || argument == Fixnum
308
+ self.new(param_description, argument)
309
+ end
310
+ end
311
+
312
+ def error
313
+ "Parameter \#{@param_name} expecting to be \#{@type.name},
314
+ got: \#{@error_value.class.name}"
315
+ end
316
+
317
+ def description
318
+ "Parameter has to be #{@type}."
319
+ end
320
+ end
321
+
322
+ Parameters of the build method:
323
+
324
+ [param_description] Instance of Restapi::ParamDescription contains all
325
+ given informations about validated parameter.
326
+ [argument] Specified validator, in our example it is +Integer+
327
+ [options] Hash with specified options, for us just
328
+ <tt>{:desc => "Company ID"}</tt>
329
+ [block] Block converted into Proc, use it as you desire. In this example nil.
330
+
331
+
332
+ == Markup
333
+
334
+ The default markup language is {RDoc}[http://rdoc.rubyforge.org/RDoc/Markup.html]. It can be changed in
335
+ config file (config.markup=) to one of these:
336
+ [Markdown] Use Restapi::Markup::Markdown.new. You need Redcarpet gem.
337
+ [Textile] Use Restapi::Markup::Textile.new. You need RedCloth gem.
338
+
339
+ Or provide you own object with <tt>to_html(text)</tt> method.
340
+ For inspiration this is how Textile look like:
341
+
342
+ class Textile
343
+ def initialize
344
+ require 'RedCloth'
345
+ end
346
+ def to_html(text)
347
+ RedCloth.new(text).to_html
348
+ end
349
+ end
350
+
351
+ == Static page
352
+
353
+ To generate static version of documentation run <tt>rake restapi:static</tt> task.
354
+ It will create folder with one-page documentation in your public directory. Rename
355
+ or delete it if you want to use 'normal' dynamic version again.
356
+
357
+ == CLI client
358
+
359
+ If you provide enough info about your API, you can generate simple CLI client. It is rather skeleton but sufficient for simple use. There is rake task for it: <tt>rake restapi:client</tt>. You can run it with two arguments <tt>rake restapi:client[http://api.example.com,.json]</tt>. The first argument is API base URL (default is http://localhost:3000). Value of second argument is appended to every URL (empty by default) which can be used to specify format. This two values can be also set afterwards from your environment as API_URL and URL_APPEND.
360
+
361
+ This task create *clients* directory with two files. <tt>Base.rb</tt> contains {Weary}[https://github.com/mwunsch/weary] clients which you can use in your own program, for howto look at {Weary}[https://github.com/mwunsch/weary] documentation. <tt>cli.thor</tt> contains {Thor}[https://github.com/wycats/thor] classes for easy interaction from cli.
362
+
363
+ Example usage:
364
+
365
+ thor list # list of all available resources and methods
366
+ thor help users:show # method and its parameters description
367
+ thor users:show --id=5 --session=abc # get /users/5?session=abc and print response body
368
+ thor users:create --user=username:foo password:bar
369
+
370
+ == TODO
371
+
372
+ * Dynamic CLI client (read info from documentation API)
373
+ * Add documentation json API description to readme
374
+ [Ideas] * PDF documentation generator
375
+ * Possibility to create requests from web documentation and check responses
2
376
 
3
- {<img src="https://secure.travis-ci.org/Pajk/rails-restapi.png?branch=master" alt="Build Status" />}[http://travis-ci.org/Pajk/rails-restapi]