restapi 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Gemfile +0 -1
  2. data/Gemfile.lock +0 -10
  3. data/README.rdoc +18 -12
  4. data/app/controllers/restapi/restapis_controller.rb +28 -1
  5. data/app/views/layouts/restapi/restapi.html.erb +1 -0
  6. data/app/views/restapi/restapis/_params.html.erb +22 -0
  7. data/app/views/restapi/restapis/_params_plain.html.erb +16 -0
  8. data/app/views/restapi/restapis/index.html.erb +5 -5
  9. data/app/views/restapi/restapis/method.html.erb +8 -4
  10. data/app/views/restapi/restapis/plain.html.erb +70 -0
  11. data/app/views/restapi/restapis/resource.html.erb +16 -5
  12. data/app/views/restapi/restapis/static.html.erb +4 -6
  13. data/lib/restapi.rb +2 -1
  14. data/lib/restapi/application.rb +72 -22
  15. data/lib/restapi/client/generator.rb +104 -0
  16. data/lib/restapi/client/template/Gemfile.tt +5 -0
  17. data/lib/restapi/client/template/README.tt +3 -0
  18. data/lib/restapi/client/template/base.rb.tt +33 -0
  19. data/lib/restapi/client/template/bin.rb.tt +110 -0
  20. data/lib/restapi/client/template/cli.rb.tt +25 -0
  21. data/lib/restapi/client/template/cli_command.rb.tt +129 -0
  22. data/lib/restapi/client/template/client.rb.tt +10 -0
  23. data/lib/restapi/client/template/resource.rb.tt +17 -0
  24. data/lib/restapi/dsl_definition.rb +20 -2
  25. data/lib/restapi/error_description.rb +8 -2
  26. data/lib/restapi/extractor.rb +143 -0
  27. data/lib/restapi/extractor/collector.rb +113 -0
  28. data/lib/restapi/extractor/recorder.rb +122 -0
  29. data/lib/restapi/extractor/writer.rb +356 -0
  30. data/lib/restapi/helpers.rb +10 -5
  31. data/lib/restapi/markup.rb +12 -12
  32. data/lib/restapi/method_description.rb +52 -8
  33. data/lib/restapi/param_description.rb +6 -5
  34. data/lib/restapi/railtie.rb +1 -1
  35. data/lib/restapi/resource_description.rb +1 -1
  36. data/lib/restapi/restapi_module.rb +43 -0
  37. data/lib/restapi/validator.rb +70 -3
  38. data/lib/restapi/version.rb +1 -1
  39. data/lib/tasks/restapi.rake +120 -121
  40. data/restapi.gemspec +0 -2
  41. data/spec/controllers/restapis_controller_spec.rb +41 -6
  42. data/spec/controllers/users_controller_spec.rb +51 -12
  43. data/spec/dummy/app/controllers/application_controller.rb +0 -2
  44. data/spec/dummy/app/controllers/twitter_example_controller.rb +4 -9
  45. data/spec/dummy/app/controllers/users_controller.rb +13 -6
  46. data/spec/dummy/config/initializers/restapi.rb +7 -0
  47. data/spec/dummy/doc/restapi_examples.yml +28 -0
  48. metadata +49 -76
  49. data/app/helpers/restapi/restapis_helper.rb +0 -31
data/Gemfile CHANGED
@@ -9,5 +9,4 @@ group :development, :test do
9
9
  gem "redcarpet"
10
10
  gem "RedCloth"
11
11
  gem "rake"
12
- gem "weary", ">= 1.0.1"
13
12
  end
@@ -29,7 +29,6 @@ GEM
29
29
  activesupport (3.2.3)
30
30
  i18n (~> 0.6)
31
31
  multi_json (~> 1.0)
32
- addressable (2.2.8)
33
32
  arel (3.0.2)
34
33
  builder (3.0.0)
35
34
  diff-lcs (1.1.3)
@@ -45,7 +44,6 @@ GEM
45
44
  mime-types (1.18)
46
45
  multi_json (1.2.0)
47
46
  polyglot (0.3.3)
48
- promise (0.3.0)
49
47
  rack (1.4.1)
50
48
  rack-cache (1.2)
51
49
  rack (>= 0.4)
@@ -85,7 +83,6 @@ GEM
85
83
  activesupport (>= 3.0)
86
84
  railties (>= 3.0)
87
85
  rspec (~> 2.10.0)
88
- simple_oauth (0.1.8)
89
86
  sprockets (2.1.3)
90
87
  hike (~> 1.2)
91
88
  rack (~> 1.0)
@@ -97,12 +94,6 @@ GEM
97
94
  polyglot
98
95
  polyglot (>= 0.3.1)
99
96
  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)
106
97
 
107
98
  PLATFORMS
108
99
  ruby
@@ -114,4 +105,3 @@ DEPENDENCIES
114
105
  redcarpet
115
106
  rspec-rails
116
107
  sqlite3
117
- weary (>= 1.0.1)
@@ -88,7 +88,7 @@ Example:
88
88
  config.markup = Restapi::Markup::Markdown.new
89
89
  config.reload_controllers = true
90
90
  config.api_controllers_matcher = File.join(Rails.root, "app", "controllers", "**","*.rb")
91
- config.app_info < <-DOC
91
+ config.app_info = <<-DOC
92
92
  This is where you can inform user about your application and API
93
93
  in general.
94
94
  DOC
@@ -135,7 +135,7 @@ Example:
135
135
  param :password, String, :required => true,
136
136
  :desc => "Password for login"
137
137
  end
138
- description < <-DOC
138
+ description <<-DOC
139
139
  Full description of this resource.
140
140
  DOC
141
141
  end
@@ -160,6 +160,8 @@ Then describe methods available to your API.
160
160
  choosen markup language processor.
161
161
  [example] Provide example of server response, whole communication or response type.
162
162
  It will be formatted as code.
163
+ [see] Provide reference to another method, this has to be string with
164
+ controller_name#method_name.
163
165
 
164
166
  Example:
165
167
 
@@ -175,6 +177,7 @@ Example:
175
177
  }, :desc => "proc validator"
176
178
  description "method description"
177
179
  example " 'user': {...} "
180
+ see "users#showme"
178
181
  def show
179
182
  #...
180
183
  end
@@ -356,21 +359,24 @@ or delete it if you want to use 'normal' dynamic version again.
356
359
 
357
360
  == CLI client
358
361
 
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.
362
+ 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>.
360
363
 
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.
364
+ This task create *clients* directory with client files.
365
+ It uses {REST Client}[https://github.com/archiloque/rest-client] for HTTP communication and {Thor}[https://github.com/wycats/thor] for easy interaction from cli.
362
366
 
363
367
  Example usage:
364
368
 
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
+ ./bin/client # list of all available resources
370
+ ./bin/client user # list of methods with description
371
+ ./bin/client user help show # show method description and parameters
372
+ ./bin/client help user:show
373
+ ./bin/client user show --id=5 --screen-name=pajk # get /users/5?screen_name=pajk and print response body
374
+ ./bin/client user create --user=username:foo password:bar
369
375
 
370
- == TODO
376
+ == {Extractor}[https://github.com/Pajk/rails-restapi/wiki/Extractor]
377
+
378
+ == Future features
371
379
 
372
380
  * Dynamic CLI client (read info from documentation API)
373
381
  * Add documentation json API description to readme
374
- [Ideas] * PDF documentation generator
375
- * Possibility to create requests from web documentation and check responses
376
-
382
+ * Possibility to create requests from web documentation and check responses
@@ -4,7 +4,34 @@ module Restapi
4
4
 
5
5
  def index
6
6
  respond_to do |format|
7
-
7
+
8
+ if Restapi.configuration.use_cache?
9
+ path = Restapi.configuration.doc_base_url.dup
10
+ if [:resource, :method, :format].any? { |p| params[p].to_s =~ /\W/ }
11
+ head :bad_request and return
12
+ end
13
+
14
+ path << "/" << params[:resource] if params[:resource].present?
15
+ path << "/" << params[:method] if params[:method].present?
16
+ if params[:format].present?
17
+ path << ".#{params[:format]}"
18
+ else
19
+ path << ".html"
20
+ end
21
+ cache_file = File.join(Restapi.configuration.cache_dir, path)
22
+ if File.exists?(cache_file)
23
+ content_type = case params[:format]
24
+ when "json" then "application/json"
25
+ else "text/html"
26
+ end
27
+ send_file cache_file, :type => content_type, :disposition => "inline"
28
+ else
29
+ Rails.logger.error("API doc cache not found for '#{path}'. Perhaps you have forgot to run `rake restapi:cache`")
30
+ head :not_found
31
+ end
32
+ return
33
+ end
34
+
8
35
  Restapi.reload_documentation if Restapi.configuration.reload_controllers?
9
36
  @doc = Restapi.to_json(params[:resource], params[:method])
10
37
 
@@ -2,6 +2,7 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>API documentation</title>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
5
6
  <% %w[bundled/bootstrap.min.css
6
7
  application.css
7
8
  bundled/prettify.css
@@ -0,0 +1,22 @@
1
+ <% level ||= 0 %>
2
+ <% col = 255 - level * 5 %>
3
+ <% params.each do |param| %>
4
+ <tr style='background-color:rgb(<%= "#{col},#{col},#{col}" %>);'>
5
+ <td>
6
+ <strong><%= param[:full_name] %> </strong><br>
7
+ <small>
8
+ <%= param[:required] ? 'required' : 'optional' %>
9
+ <%= param[:allow_nil] ? ', nil allowed' : '' %>
10
+ </small>
11
+ </td>
12
+ <td>
13
+ <%= param[:description].html_safe %>
14
+ <% unless param[:validator].blank? %>
15
+ <br>
16
+ Value: <%= param[:validator] %>
17
+ <% end %>
18
+ </td>
19
+ </tr>
20
+
21
+ <%= render(:partial => "params", :locals => {:level => level + 1, :params => param[:params]}) unless param[:params].blank? %>
22
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <ul>
2
+ <% params.each do |param| %>
3
+ <li>
4
+ <strong><%= param[:name] %> </strong>:
5
+ <small>
6
+ <%= param[:required] ? 'required' : 'optional' %>
7
+ <%= param[:allow_nil] ? ', nil allowed' : '' %>
8
+ <% if param[:validator] %>
9
+ [ <%= param[:validator] %> ]
10
+ <% end %>
11
+ </small>
12
+ <%= param[:description].html_safe %>
13
+ </li>
14
+ <%= render(:partial => "params_plain", :locals => {:params => param[:params]}) unless param[:params].blank? %>
15
+ <% end %>
16
+ </ul>
@@ -1,14 +1,14 @@
1
1
  <ul class='breadcrumb'>
2
- <li class='active'><a href='<%= @doc[:doc_url] %>'><%= @doc[:name] %></a></li>
2
+ <li class='active'><a href='<%= @doc[:doc_url] %>.html'><%= @doc[:name] %></a></li>
3
3
  </ul>
4
4
 
5
5
  <div><%= @doc[:info].html_safe %></div>
6
6
 
7
7
  <h1 class='page-header'>Resources</h1>
8
8
 
9
- <% @doc[:resources].each do |key, api| %>
9
+ <% @doc[:resources].sort_by(&:first).each do |key, api| %>
10
10
  <h2>
11
- <a href='<%= api[:doc_url] %>'><%= api[:name] %></a><br>
11
+ <a href='<%= api[:doc_url] %>.html'><%= api[:name] %></a><br>
12
12
  <small><%= api[:short_description] %></small>
13
13
  </h2>
14
14
  <table class='table'>
@@ -22,7 +22,7 @@
22
22
  <% api[:methods].each do |m| %>
23
23
  <% m[:apis].each do |a| %>
24
24
  <tr>
25
- <td><a href='<%= m[:doc_url] %>'><%= a[:http_method] %> <%= a[:api_url] %></a></td>
25
+ <td><a href='<%= m[:doc_url] %>.html'><%= a[:http_method] %> <%= a[:api_url] %></a></td>
26
26
  <td width='60%'><%= a[:short_description] %></td>
27
27
  </tr>
28
28
  <% end %>
@@ -33,4 +33,4 @@
33
33
 
34
34
  <% content_for :restapi_footer do %>
35
35
  <%= raw @doc[:copyright] %>
36
- <% end %>
36
+ <% end %>
@@ -1,10 +1,10 @@
1
1
  <ul class='breadcrumb'>
2
2
  <li>
3
- <a href='<%= @doc[:doc_url] %>'><%= @doc[:name] %></a>
3
+ <a href='<%= @doc[:doc_url] %>.html'><%= @doc[:name] %></a>
4
4
  <span class='divider'>/</span>
5
5
  </li>
6
6
  <li>
7
- <a href='<%= @resource[:doc_url] %>'><%= @resource[:name] %></a>
7
+ <a href='<%= @resource[:doc_url] %>.html'><%= @resource[:name] %></a>
8
8
  <span class='divider'>/</span>
9
9
  </li>
10
10
  <li class='active'><%= @method[:name] %></li>
@@ -20,6 +20,10 @@
20
20
  <% end %>
21
21
 
22
22
  <div>
23
+ <% unless @method[:see_url].blank? %>
24
+ Also see <%= link_to @method[:see], @method[:see_url] %>.
25
+ <% end %>
26
+
23
27
  <%= raw @method[:full_description] %>
24
28
 
25
29
  <% unless @method[:examples].blank? %>
@@ -48,7 +52,7 @@
48
52
  </tr>
49
53
  </thead>
50
54
  <tbody>
51
- <%= print_nested_params(@method) %>
55
+ <%= render(:partial => "params", :locals => {:params => @method[:params]}) %>
52
56
  </tbody>
53
57
  </table>
54
58
  <% end %>
@@ -56,4 +60,4 @@
56
60
 
57
61
  <% content_for :restapi_footer do %>
58
62
  <%= raw @doc[:copyright] %>
59
- <% end %>
63
+ <% end %>
@@ -0,0 +1,70 @@
1
+ <% @doc[:resources].sort_by(&:first).each do |key, resource| %>
2
+ <h4><a href='#<%= key %>'><%= resource[:name] %></a></h4>
3
+ <ul>
4
+ <% resource[:methods].each do |method| %>
5
+ <li><a href='#<%= key %>-<%= method[:name] %>'><%= method[:name] %></a></li>
6
+ <% end %>
7
+ </ul>
8
+ <% end %>
9
+
10
+
11
+ <% @doc[:resources].sort_by(&:first).each do |key, resource| %>
12
+
13
+ <hr/>
14
+
15
+ <div>
16
+ <h2 id="<%= key %>">
17
+ <a href='#<%= key %>'><%= resource[:name] %></a><br>
18
+ <small><%= raw resource[:short_description] %></small>
19
+ </h2>
20
+ </div>
21
+
22
+ <% unless resource[:full_description].blank? %>
23
+ <div><%= raw resource[:full_description] %></div>
24
+ <% end %>
25
+
26
+ <div>
27
+
28
+ <% resource[:methods].each do |method| %>
29
+ <hr/>
30
+
31
+ <h3 id="<%= "#{key}-#{method[:name]}" %>">
32
+ <a href='#<%= key %>'><%= resource[:name] %></a> / <a href='#<%= "#{key}-#{method[:name]}" %>'><%= method[:name] %></a>
33
+ </h3>
34
+
35
+ <div>
36
+ <% method[:apis].each do |api| %>
37
+ <h4>
38
+ <%= api[:http_method] %> <%= api[:api_url] %>
39
+ <br>
40
+ <small><%= raw api[:short_description] %></small>
41
+ </h4>
42
+ <% end %>
43
+ </div>
44
+
45
+ <div>
46
+ <%= raw method[:full_description] %>
47
+ <% unless method[:examples].blank? %>
48
+ <h4>Examples</h4>
49
+ <% method[:examples].each do |example| %>
50
+ <pre class="wiki"><%= example %></pre>
51
+ <% end %>
52
+ <% end %>
53
+
54
+ <% unless method[:errors].blank? %>
55
+ <h4>Errors</h4>
56
+ <% method[:errors].each do |err| %>
57
+ <%= err.code %>
58
+ <%= err.description %>
59
+ <br>
60
+ <% end %>
61
+ <% end %>
62
+
63
+ <% unless method[:params].blank? %>
64
+ <h4>Params</h4>
65
+ <%= render(:partial => "params_plain", :locals => {:params => method[:params]}) %>
66
+ <% end %>
67
+ </div>
68
+ <% end %>
69
+ </div>
70
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  <ul class='breadcrumb'>
2
- <li><a href='<%= @doc[:doc_url] %>'><%= @doc[:name] %></a><span class='divider'>/</span></li>
2
+ <li><a href='<%= @doc[:doc_url] %>.html'><%= @doc[:name] %></a><span class='divider'>/</span></li>
3
3
  <li class='active'><%= @resource[:name] %></li>
4
4
  </ul>
5
5
 
@@ -20,7 +20,7 @@
20
20
  <% @resource[:methods].each do |m| %>
21
21
  <hr>
22
22
  <div class='pull-right small'>
23
- <a href='<%= m[:doc_url] %>'> >>> </a>
23
+ <a href='<%= m[:doc_url] %>.html'> >>> </a>
24
24
  </div>
25
25
  <div>
26
26
  <% m[:apis].each do |api| %>
@@ -36,6 +36,10 @@
36
36
  <% end %>
37
37
  </div>
38
38
 
39
+ <% unless m[:see_url].blank? %>
40
+ Also see <%= link_to m[:see], m[:see_url] %>
41
+ <% end %>
42
+
39
43
  <div id='description-<%= m[:name] %>' class='collapse accordion-body'>
40
44
 
41
45
  <%= raw m[:full_description] %>
@@ -47,7 +51,14 @@
47
51
  <br>
48
52
  <% end %>
49
53
  <% end %>
50
-
54
+
55
+ <% unless m[:examples].blank? %>
56
+ <h3>Examples</h3>
57
+ <% m[:examples].each do |example| %>
58
+ <pre><%= example %></pre>
59
+ <% end %>
60
+ <% end %>
61
+
51
62
  <% unless m[:params].blank? %>
52
63
  <h3>Params</h3>
53
64
  <table class='table'>
@@ -58,7 +69,7 @@
58
69
  </tr>
59
70
  </thead>
60
71
  <tbody>
61
- <%= print_nested_params(m) %>
72
+ <%= render(:partial => "params", :locals => {:params => m[:params]}) %>
62
73
  </tbody>
63
74
  </table>
64
75
  <% end %>
@@ -68,4 +79,4 @@
68
79
 
69
80
  <% content_for :restapi_footer do %>
70
81
  <%= raw @doc[:copyright] %>
71
- <% end %>
82
+ <% end %>
@@ -1,6 +1,4 @@
1
- <% @doc = doc %>
2
-
3
- <% @doc[:resources].each do |key, resource| %>
1
+ <% @doc[:resources].sort_by(&:first).each do |key, resource| %>
4
2
  <h4><a href='#<%= key %>'><%= resource[:name] %></a></h4>
5
3
  <ul>
6
4
  <% resource[:methods].each do |method| %>
@@ -15,7 +13,7 @@
15
13
 
16
14
  <hr>
17
15
 
18
- <% @doc[:resources].each do |key, resource| %>
16
+ <% @doc[:resources].sort_by(&:first).each do |key, resource| %>
19
17
 
20
18
  <ul class='breadcrumb' id='<%= key %>'>
21
19
  <li><a href='#'><%= @doc[:name] %></a><span class='divider'>/</span></li>
@@ -89,7 +87,7 @@
89
87
  </tr>
90
88
  </thead>
91
89
  <tbody>
92
- <%= print_nested_params(method) %>
90
+ <%= render(:partial => "params", :locals => {:params => method[:params]}) %>
93
91
  </tbody>
94
92
  </table>
95
93
  <% end %>
@@ -100,4 +98,4 @@
100
98
 
101
99
  <% content_for :restapi_footer do %>
102
100
  <%= raw @doc[:copyright] %>
103
- <% end %>
101
+ <% end %>
@@ -8,4 +8,5 @@ require "restapi/error_description"
8
8
  require "restapi/validator"
9
9
  require "restapi/dsl_definition"
10
10
  require "restapi/railtie"
11
- require "restapi/version"
11
+ require 'restapi/extractor'
12
+ require "restapi/version"
@@ -1,4 +1,5 @@
1
1
  require 'restapi/static_dispatcher'
2
+ require 'yaml'
2
3
 
3
4
  module Restapi
4
5
 
@@ -11,16 +12,16 @@ module Restapi
11
12
  end
12
13
  end
13
14
 
14
- attr_accessor :last_api_args, :last_errors, :last_params, :last_description, :last_examples
15
+ attr_accessor :last_api_args, :last_errors, :last_params, :last_description, :last_examples, :last_see
15
16
  attr_reader :method_descriptions, :resource_descriptions
16
-
17
- def initialize
17
+
18
+ def initialize
18
19
  super
19
20
  @method_descriptions = Hash.new
20
21
  @resource_descriptions = Hash.new
21
22
  clear_last
22
23
  end
23
-
24
+
24
25
  # create new method api description
25
26
  def define_method_description(controller, method_name)
26
27
  # create new or get existing api
@@ -53,17 +54,25 @@ module Restapi
53
54
  def add_example(example)
54
55
  @last_examples << example.strip_heredoc
55
56
  end
56
-
57
+
57
58
  # check if there is some saved description
58
59
  def restapi_provided?
59
60
  true unless last_api_args.blank?
60
61
  end
61
62
 
62
63
  # get api for given method
63
- def get_method_description(resource_name, method_name)
64
+ #
65
+ # There are two ways how this method can be used:
66
+ # 1) Specify both parameters
67
+ # resource_name: controller class or string with resource name (plural)
68
+ # method_name: name of the method (string or symbol)
69
+ # 2) Specify only first parameter:
70
+ # resource_name: string containing both resource and method name joined
71
+ # with # (eg. "users#create")
72
+ def get_method_description(resource_name, method_name = nil)
64
73
  resource_name = get_resource_name(resource_name)
65
-
66
- @method_descriptions[[resource_name, method_name].join('#')]
74
+ key = method_name.blank? ? resource_name : [resource_name, method_name].join('#')
75
+ @method_descriptions[key]
67
76
  end
68
77
  alias :[] :get_method_description
69
78
 
@@ -99,27 +108,34 @@ module Restapi
99
108
  @last_params = []
100
109
  @last_description = nil
101
110
  @last_examples = []
111
+ @last_see = nil
102
112
  end
103
-
113
+
104
114
  # Return the current description, clearing it in the process.
105
115
  def get_description
106
116
  desc = @last_description
107
117
  @last_description = nil
108
118
  desc
109
119
  end
110
-
120
+
111
121
  def get_errors
112
122
  errors = @last_errors.clone
113
123
  @last_errors.clear
114
124
  errors
115
125
  end
116
-
126
+
117
127
  def get_api_args
118
128
  api_args = @last_api_args.clone
119
129
  @last_api_args.clear
120
130
  api_args
121
131
  end
122
-
132
+
133
+ def get_see
134
+ see = @last_see
135
+ @last_see = nil
136
+ see
137
+ end
138
+
123
139
  def get_params
124
140
  params = @last_params.clone
125
141
  @last_params.clear
@@ -131,9 +147,24 @@ module Restapi
131
147
  @last_examples.clear
132
148
  examples
133
149
  end
134
-
150
+
151
+ def recorded_examples
152
+ return @recorded_examples if @recorded_examples
153
+ tape_file = File.join(Rails.root,"doc","restapi_examples.yml")
154
+ if File.exists?(tape_file)
155
+ @recorded_examples = YAML.load_file(tape_file)
156
+ else
157
+ @recorded_examples = {}
158
+ end
159
+ @recorded_examples
160
+ end
161
+
162
+ def reload_examples
163
+ @recorded_examples = nil
164
+ end
165
+
135
166
  def to_json(resource_name, method_name)
136
-
167
+
137
168
  _resources = if resource_name.blank?
138
169
  # take just resources which have some methods because
139
170
  # we dont want to show eg ApplicationController as resource
@@ -150,26 +181,45 @@ module Restapi
150
181
  :name => Restapi.configuration.app_name,
151
182
  :info => Restapi.configuration.app_info,
152
183
  :copyright => Restapi.configuration.copyright,
153
- :doc_url => "#{ENV["RAILS_RELATIVE_URL_ROOT"]}#{Restapi.configuration.doc_base_url}",
184
+ :doc_url => Restapi.full_url(""),
154
185
  :api_url => Restapi.configuration.api_base_url,
155
186
  :resources => _resources
156
187
  }
157
188
  }
158
189
  end
159
190
 
191
+ def api_controllers_paths
192
+ Dir[Restapi.configuration.api_controllers_matcher]
193
+ end
194
+
160
195
  def reload_documentation
161
- Dir[Restapi.configuration.api_controllers_matcher].each {|f| load f}
196
+ reload_examples
197
+ api_controllers_paths.each do |f|
198
+ load_controller_from_file f
199
+ end
200
+ end
201
+
202
+ # Is there a reason to interpret the DSL for this run?
203
+ # with specific setting for some environment there is no reason the dsl
204
+ # should be interpreted (e.g. no validations and doc from cache)
205
+ def active_dsl?
206
+ Restapi.configuration.validate? || ! Restapi.configuration.use_cache? || Restapi.configuration.force_dsl?
162
207
  end
163
208
 
164
209
  private
165
210
 
166
- def get_resource_name(klass)
167
- if klass.class == String
168
- klass
169
- elsif klass.class == Class && ActionController::Base.descendants.include?(klass)
170
- klass.controller_name
171
- end
211
+ def get_resource_name(klass)
212
+ if klass.class == String
213
+ klass
214
+ elsif klass.respond_to?(:controller_name)
215
+ klass.controller_name
172
216
  end
217
+ end
218
+
219
+ def load_controller_from_file(controller_file)
220
+ controller_class_name = controller_file.gsub(/\A.*\/app\/controllers\//,"").gsub(/\.\w*\Z/,"").camelize
221
+ controller_class_name.constantize
222
+ end
173
223
 
174
224
  end
175
225
  end