apipie-rails 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rvmrc +1 -1
- data/Gemfile.lock +1 -1
- data/README.rdoc +5 -1
- data/app/views/apipie/apipies/method.html.erb +7 -2
- data/app/views/apipie/apipies/plain.html.erb +2 -2
- data/app/views/apipie/apipies/resource.html.erb +13 -4
- data/app/views/apipie/apipies/static.html.erb +2 -2
- data/lib/apipie/application.rb +8 -1
- data/lib/apipie/client/generator.rb +7 -2
- data/lib/apipie/client/template/base.rb.tt +5 -2
- data/lib/apipie/client/template/client.gemspec.tt +1 -1
- data/lib/apipie/dsl_definition.rb +8 -0
- data/lib/apipie/error_description.rb +5 -1
- data/lib/apipie/method_description.rb +21 -2
- data/lib/apipie/resource_description.rb +13 -1
- data/lib/apipie/version.rb +1 -1
- data/rubygem-apipie-rails.spec +12 -2
- data/spec/controllers/users_controller_spec.rb +24 -13
- data/spec/dummy/app/controllers/users_controller.rb +4 -0
- data/spec/dummy/db/.gitkeep +0 -0
- metadata +5 -2
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use 1.8.7@apipie
|
1
|
+
rvm use 1.8.7@apipie --create
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -108,6 +108,7 @@ be checked in every request.
|
|
108
108
|
[short] One line short description.
|
109
109
|
[path] Relative URL path of this resource.
|
110
110
|
[version] Version of this resource API, use arbitrary string.
|
111
|
+
[formats] Resource level request / response formats.
|
111
112
|
[param] The very same parameter description as you will use method
|
112
113
|
description. Generally use this for parameters that apply
|
113
114
|
to every method in the controller (such as :user hash).
|
@@ -125,6 +126,7 @@ Example:
|
|
125
126
|
short 'Site members'
|
126
127
|
path '/users'
|
127
128
|
version '1.0 - 3.4.2012'
|
129
|
+
formats ['json', 'xml']
|
128
130
|
param :id, Fixnum, :desc => "User ID", :required => false
|
129
131
|
param :user, Hash, :desc => 'Param description for all methods' do
|
130
132
|
param :username, String, :required => true,
|
@@ -151,6 +153,7 @@ Then describe methods available to your API.
|
|
151
153
|
You can use this +api+ method more than once for one method. It could
|
152
154
|
be useful when there are more routes mapped to it.
|
153
155
|
[param] Look at Parameter description section for details.
|
156
|
+
[formats] Method level request / response formats.
|
154
157
|
[error] Describe each possible error that can happend what calling this
|
155
158
|
method. HTTP response code and description can be provided.
|
156
159
|
[description] Full method description which will be converted to HTML by
|
@@ -173,6 +176,7 @@ Example:
|
|
173
176
|
val == "param value" ? true : "The only good value is 'param value'."
|
174
177
|
}, :desc => "proc validator"
|
175
178
|
description "method description"
|
179
|
+
formats ['json', 'jsonp', 'xml']
|
176
180
|
example " 'user': {...} "
|
177
181
|
see "users#showme"
|
178
182
|
def show
|
@@ -300,7 +304,7 @@ So we create apipie_validators.rb initializer with this content:
|
|
300
304
|
|
301
305
|
def validate(value)
|
302
306
|
return false if value.nil?
|
303
|
-
!!(value.to_s =~
|
307
|
+
!!(value.to_s =~ /^[-+]?[0-9]+$/)
|
304
308
|
end
|
305
309
|
|
306
310
|
def self.build(param_description, argument, options, block)
|
@@ -33,11 +33,16 @@
|
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
35
35
|
|
36
|
+
<% unless @method[:formats].blank? %>
|
37
|
+
<h2>Supported Formats</h2>
|
38
|
+
<%= @method[:formats].join(', ') %>
|
39
|
+
<% end %>
|
40
|
+
|
36
41
|
<% unless @method[:errors].blank? %>
|
37
42
|
<h2>Errors</h2>
|
38
43
|
<% @method[:errors].each do |err| %>
|
39
|
-
<%= err
|
40
|
-
<%= err
|
44
|
+
<%= err[:code] %>
|
45
|
+
<%= err[:description] %>
|
41
46
|
<br>
|
42
47
|
<% end %>
|
43
48
|
<% end %>
|
@@ -10,11 +10,15 @@
|
|
10
10
|
</h1>
|
11
11
|
</div>
|
12
12
|
|
13
|
-
|
14
13
|
<% unless @resource[:full_description].blank? %>
|
15
14
|
<div><%= raw @resource[:full_description] %></div>
|
16
15
|
<% end %>
|
17
16
|
|
17
|
+
<% unless @resource[:formats].blank? %>
|
18
|
+
<h2>Supported Formats</h2>
|
19
|
+
<%= @resource[:formats].join(', ') %>
|
20
|
+
<% end %>
|
21
|
+
|
18
22
|
<div class='accordion' id='accordion'>
|
19
23
|
|
20
24
|
<% @resource[:methods].each do |m| %>
|
@@ -41,13 +45,18 @@
|
|
41
45
|
<% end %>
|
42
46
|
|
43
47
|
<div id='description-<%= m[:name] %>' class='collapse accordion-body'>
|
44
|
-
|
45
48
|
<%= raw m[:full_description] %>
|
49
|
+
|
50
|
+
<% unless m[:formats].blank? %>
|
51
|
+
<h3>Supported Formats</h3>
|
52
|
+
<%= m[:formats].join(', ') %>
|
53
|
+
<% end %>
|
54
|
+
|
46
55
|
<% unless m[:errors].blank? %>
|
47
56
|
<h3>Errors</h3>
|
48
57
|
<% m[:errors].each do |err| %>
|
49
|
-
<%= err
|
50
|
-
<%= err
|
58
|
+
<%= err[:code] %>
|
59
|
+
<%= err[:description] %>
|
51
60
|
<br>
|
52
61
|
<% end %>
|
53
62
|
<% end %>
|
data/lib/apipie/application.rb
CHANGED
@@ -12,7 +12,7 @@ module Apipie
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_accessor :last_api_args, :last_errors, :last_params, :last_description, :last_examples, :last_see
|
15
|
+
attr_accessor :last_api_args, :last_errors, :last_params, :last_description, :last_examples, :last_see, :last_formats
|
16
16
|
attr_reader :method_descriptions, :resource_descriptions
|
17
17
|
|
18
18
|
def initialize
|
@@ -109,6 +109,7 @@ module Apipie
|
|
109
109
|
@last_description = nil
|
110
110
|
@last_examples = []
|
111
111
|
@last_see = nil
|
112
|
+
@last_formats = []
|
112
113
|
end
|
113
114
|
|
114
115
|
# Return the current description, clearing it in the process.
|
@@ -136,6 +137,12 @@ module Apipie
|
|
136
137
|
see
|
137
138
|
end
|
138
139
|
|
140
|
+
def get_formats
|
141
|
+
formats = @last_formats
|
142
|
+
@last_formats = nil
|
143
|
+
formats
|
144
|
+
end
|
145
|
+
|
139
146
|
def get_params
|
140
147
|
params = @last_params.clone
|
141
148
|
@last_params.clear
|
@@ -68,12 +68,17 @@ module Apipie
|
|
68
68
|
|
69
69
|
protected
|
70
70
|
|
71
|
+
def camelizer(string)
|
72
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
73
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$2.capitalize}" }
|
74
|
+
end
|
75
|
+
|
71
76
|
def class_base
|
72
|
-
@class_base ||= name
|
77
|
+
@class_base ||= camelizer(name)
|
73
78
|
end
|
74
79
|
|
75
80
|
def class_suffix
|
76
|
-
@class_suffix ||= suffix
|
81
|
+
@class_suffix ||= camelizer(suffix)
|
77
82
|
end
|
78
83
|
|
79
84
|
def plaintext(text)
|
@@ -17,8 +17,11 @@ module <%= class_base %><%= class_suffix %>
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def call(method, path, payload = nil)
|
20
|
-
|
21
|
-
|
20
|
+
if payload && (method == :post || method == :put)
|
21
|
+
# TODO: is this neccessary? RestClient converts it automaticaly for me.
|
22
|
+
payload = payload.to_json
|
23
|
+
end
|
24
|
+
ret = client[path].send(*([method, payload].compact))
|
22
25
|
data = begin
|
23
26
|
JSON.parse(ret.body)
|
24
27
|
rescue JSON::ParserError
|
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = <%= class_base %><%= class_suffix %>::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'thor', '>= 0.15.4'
|
18
|
+
<% if all? %>gem.add_dependency 'thor', '>= 0.15.4'<% end %>
|
19
19
|
gem.add_dependency 'json'
|
20
20
|
gem.add_dependency 'rest-client', '>= 1.6.1'
|
21
21
|
gem.add_dependency 'oauth'
|
@@ -66,6 +66,14 @@ module Apipie
|
|
66
66
|
Apipie.add_example(example)
|
67
67
|
end
|
68
68
|
|
69
|
+
# Describe available request/response formats
|
70
|
+
#
|
71
|
+
# formats ['json', 'jsonp', 'xml']
|
72
|
+
def formats(formats) #:doc:
|
73
|
+
return unless Apipie.active_dsl?
|
74
|
+
Apipie.last_formats = formats
|
75
|
+
end
|
76
|
+
|
69
77
|
# Describe possible errors
|
70
78
|
#
|
71
79
|
# Example:
|
@@ -23,7 +23,7 @@ module Apipie
|
|
23
23
|
|
24
24
|
end
|
25
25
|
|
26
|
-
attr_reader :
|
26
|
+
attr_reader :full_description, :method, :resource, :apis, :examples, :see, :formats
|
27
27
|
|
28
28
|
def initialize(method, resource, app)
|
29
29
|
@method = method
|
@@ -31,6 +31,7 @@ module Apipie
|
|
31
31
|
|
32
32
|
@apis = app.get_api_args
|
33
33
|
@see = app.get_see
|
34
|
+
@formats = app.get_formats
|
34
35
|
|
35
36
|
desc = app.get_description || ''
|
36
37
|
@full_description = Apipie.markup_to_html(desc)
|
@@ -72,6 +73,19 @@ module Apipie
|
|
72
73
|
all_params.find_all(&:validator)
|
73
74
|
end
|
74
75
|
|
76
|
+
def errors
|
77
|
+
return @merged_errors if @merged_errors
|
78
|
+
@merged_errors = []
|
79
|
+
if @resource
|
80
|
+
# exclude overwritten parent errors
|
81
|
+
@merged_errors = @resource._errors_ordered.find_all do |err|
|
82
|
+
!@errors.any? { |e| e.code == err.code }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
@merged_errors.concat(@errors)
|
86
|
+
return @merged_errors
|
87
|
+
end
|
88
|
+
|
75
89
|
def doc_url
|
76
90
|
Apipie.full_url("#{@resource._id}/#{@method}")
|
77
91
|
end
|
@@ -100,13 +114,18 @@ module Apipie
|
|
100
114
|
@see
|
101
115
|
end
|
102
116
|
|
117
|
+
def formats
|
118
|
+
@formats || @resource._formats
|
119
|
+
end
|
120
|
+
|
103
121
|
def to_json
|
104
122
|
{
|
105
123
|
:doc_url => doc_url,
|
106
124
|
:name => @method,
|
107
125
|
:apis => method_apis_to_json,
|
126
|
+
:formats => formats,
|
108
127
|
:full_description => @full_description,
|
109
|
-
:errors =>
|
128
|
+
:errors => errors.map(&:to_json),
|
110
129
|
:params => params_ordered.map(&:to_json).flatten,
|
111
130
|
:examples => @examples,
|
112
131
|
:see => @see,
|
@@ -8,14 +8,16 @@ module Apipie
|
|
8
8
|
# methods - array of keys to Apipie.method_descriptions (array of Apipie::MethodDescription)
|
9
9
|
# name - human readable alias of resource (Articles)
|
10
10
|
# id - resouce name
|
11
|
+
# formats - acceptable request/response format types
|
11
12
|
class ResourceDescription
|
12
13
|
|
13
14
|
attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
|
14
|
-
:_path, :_version, :_name, :_params_ordered
|
15
|
+
:_path, :_version, :_name, :_params_ordered, :_errors_ordered, :_formats
|
15
16
|
|
16
17
|
def initialize(controller, resource_name, &block)
|
17
18
|
@_methods = []
|
18
19
|
@_params_ordered = []
|
20
|
+
@_errors_ordered = []
|
19
21
|
|
20
22
|
@controller = controller
|
21
23
|
@_id = resource_name
|
@@ -24,6 +26,7 @@ module Apipie
|
|
24
26
|
@_full_description = ""
|
25
27
|
@_short_description = ""
|
26
28
|
@_path = ""
|
29
|
+
@_formats = []
|
27
30
|
|
28
31
|
block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
|
29
32
|
end
|
@@ -33,10 +36,18 @@ module Apipie
|
|
33
36
|
@_params_ordered << param_description
|
34
37
|
end
|
35
38
|
|
39
|
+
def error(*args)
|
40
|
+
error_description = Apipie::ErrorDescription.new(args)
|
41
|
+
@_errors_ordered << error_description
|
42
|
+
end
|
43
|
+
|
44
|
+
|
36
45
|
def path(path); @_path = path; end
|
37
46
|
|
38
47
|
def version(version); @_version = version; end
|
39
48
|
|
49
|
+
def formats(formats); @_formats = formats; end
|
50
|
+
|
40
51
|
def name(name); @_name = name; end
|
41
52
|
|
42
53
|
def short(short); @_short_description = short; end
|
@@ -76,6 +87,7 @@ module Apipie
|
|
76
87
|
:short_description => @_short_description,
|
77
88
|
:full_description => @_full_description,
|
78
89
|
:version => @_version,
|
90
|
+
:formats => @_formats,
|
79
91
|
:methods => _methods
|
80
92
|
}
|
81
93
|
end
|
data/lib/apipie/version.rb
CHANGED
data/rubygem-apipie-rails.spec
CHANGED
@@ -10,14 +10,16 @@
|
|
10
10
|
|
11
11
|
Summary: Rails API documentation tool and client generator.
|
12
12
|
Name: rubygem-%{gemname}
|
13
|
-
Version: 0.0.
|
14
|
-
Release:
|
13
|
+
Version: 0.0.9
|
14
|
+
Release: 0%{?dist}
|
15
15
|
Group: Development/Libraries
|
16
16
|
License: MIT
|
17
17
|
URL: http://github.com/Pajk/apipie-rails
|
18
18
|
Source0: http://rubygems.org/downloads/%{gemname}-%{version}.gem
|
19
19
|
Requires: ruby(abi) >= %{rubyabi}
|
20
|
+
Requires: rubygems
|
20
21
|
BuildRequires: ruby(abi) >= %{rubyabi}
|
22
|
+
BuildRequires: rubygems
|
21
23
|
BuildArch: noarch
|
22
24
|
Provides: rubygem(%{gemname}) = %{version}
|
23
25
|
|
@@ -56,6 +58,7 @@ cp -a .%{gemdir}/* \
|
|
56
58
|
%exclude %{geminstdir}/.rvmrc
|
57
59
|
%exclude %{geminstdir}/.travis.yml
|
58
60
|
%exclude %{geminstdir}/rubygem-apipie-rails.spec
|
61
|
+
%exclude %{geminstdir}/.yardoc
|
59
62
|
%exclude %{gemdir}/cache/%{gemname}-%{version}.gem
|
60
63
|
%exclude %{gemdir}/doc/%{gemname}-%{version}
|
61
64
|
|
@@ -65,6 +68,13 @@ cp -a .%{gemdir}/* \
|
|
65
68
|
%doc %{geminstdir}/NOTICE
|
66
69
|
|
67
70
|
%changelog
|
71
|
+
* Thu Jul 26 2012 Pavel Pokorný <pajkycz@gmail.com> 0.0.8-3
|
72
|
+
- Require rubygems in spec file
|
73
|
+
|
74
|
+
* Thu Jul 26 2012 Pavel Pokorný <pajkycz@gmail.com> 0.0.8-2
|
75
|
+
- New version of apipie-rails gem
|
76
|
+
- Generated client improvements
|
77
|
+
|
68
78
|
* Thu Jul 26 2012 Pavel Pokorný <pajkycz@gmail.com> 0.0.7-2
|
69
79
|
- removed doc files from rpm
|
70
80
|
|
@@ -1,15 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
def compare_hashes(h1, h2)
|
4
|
-
h1.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
val.
|
9
|
-
compare_hashes val
|
4
|
+
if h1.is_a? String
|
5
|
+
h1.should eq(h2)
|
6
|
+
else
|
7
|
+
h1.each do |key, val|
|
8
|
+
if val.is_a? Hash
|
9
|
+
compare_hashes val, h2[key]
|
10
|
+
elsif val.is_a? Array
|
11
|
+
val.each_with_index do |v, i|
|
12
|
+
compare_hashes val[i], h2[key][i]
|
13
|
+
end
|
14
|
+
else
|
15
|
+
val.should eq(h2[key])
|
10
16
|
end
|
11
|
-
else
|
12
|
-
val.should eq(h2[key])
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -34,6 +38,7 @@ describe UsersController do
|
|
34
38
|
subject._path.should eq('/users')
|
35
39
|
subject._version.should eq('1.0 - 3.4.2012')
|
36
40
|
subject._name.should eq('Members')
|
41
|
+
subject._formats.should eq(['json'])
|
37
42
|
end
|
38
43
|
|
39
44
|
it "should contain params defined on resource level" do
|
@@ -202,6 +207,7 @@ describe UsersController do
|
|
202
207
|
it "should contain basic info about method" do
|
203
208
|
a = Apipie[UsersController, :create]
|
204
209
|
a.apis.count.should == 1
|
210
|
+
a.formats.should eq(['json'])
|
205
211
|
api = a.apis.first
|
206
212
|
api.short_description.should eq("Create user")
|
207
213
|
api.api_url.should eq("/api/users")
|
@@ -213,6 +219,7 @@ describe UsersController do
|
|
213
219
|
b.resource._id.should eq('users')
|
214
220
|
|
215
221
|
b.apis.count.should == 1
|
222
|
+
b.formats.should eq(['json', 'jsonp'])
|
216
223
|
api = b.apis.first
|
217
224
|
api.short_description.should eq("Show user profile")
|
218
225
|
api.api_url.should eq("#{Apipie.configuration.api_base_url}/users/:id")
|
@@ -246,10 +253,12 @@ describe UsersController do
|
|
246
253
|
it "should contain possible errors description" do
|
247
254
|
a = Apipie.get_method_description(UsersController, :show)
|
248
255
|
|
249
|
-
a.errors[0].code.should eq(
|
250
|
-
a.errors[0].description.should
|
251
|
-
a.errors[1].code.should eq(
|
252
|
-
a.errors[1].description.should eq("
|
256
|
+
a.errors[0].code.should eq(500)
|
257
|
+
a.errors[0].description.should include("crashed")
|
258
|
+
a.errors[1].code.should eq(401)
|
259
|
+
a.errors[1].description.should eq("Unauthorized")
|
260
|
+
a.errors[2].code.should eq(404)
|
261
|
+
a.errors[2].description.should eq("Not Found")
|
253
262
|
end
|
254
263
|
|
255
264
|
it "should contain all params description" do
|
@@ -276,9 +285,11 @@ describe UsersController do
|
|
276
285
|
it "should be described by valid json" do
|
277
286
|
json = Apipie[UsersController, :two_urls].to_json
|
278
287
|
expected_hash = {
|
279
|
-
:errors => [
|
288
|
+
:errors => [{:code=>404, :description=>"Missing"},
|
289
|
+
{:code=>500, :description=>"Server crashed for some <%= reason %>"}],
|
280
290
|
:examples => [],
|
281
291
|
:doc_url => "#{Apipie.configuration.doc_base_url}/users/two_urls",
|
292
|
+
:formats=>["json"],
|
282
293
|
:full_description => '',
|
283
294
|
:params => [{:full_name=>"oauth",
|
284
295
|
:required=>false,
|
@@ -5,11 +5,14 @@ class UsersController < ApplicationController
|
|
5
5
|
short 'Site members'
|
6
6
|
path '/users'
|
7
7
|
version '1.0 - 3.4.2012'
|
8
|
+
formats ['json']
|
8
9
|
param :id, Fixnum, :desc => "User ID", :required => false
|
9
10
|
param :resource_param, Hash, :desc => 'Param description for all methods' do
|
10
11
|
param :ausername, String, :desc => "Username for login", :required => true
|
11
12
|
param :apassword, String, :desc => "Password for login", :required => true
|
12
13
|
end
|
14
|
+
error 404, "Missing"
|
15
|
+
error 500, "Server crashed for some <%= reason %>"
|
13
16
|
description <<-EOS
|
14
17
|
== Long description
|
15
18
|
|
@@ -163,6 +166,7 @@ class UsersController < ApplicationController
|
|
163
166
|
More builder documentation can be found at http://builder.rubyforge.org.
|
164
167
|
eos
|
165
168
|
api :GET, "/users/:id", "Show user profile"
|
169
|
+
formats ['json', 'jsonp']
|
166
170
|
error 401, "Unauthorized"
|
167
171
|
error :code => 404, :description => "Not Found"
|
168
172
|
param :id, Integer, :desc => "user id", :required => true
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apipie-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-07-
|
13
|
+
date: 2012-07-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec-rails
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- spec/dummy/config/initializers/session_store.rb
|
223
223
|
- spec/dummy/config/locales/en.yml
|
224
224
|
- spec/dummy/config/routes.rb
|
225
|
+
- spec/dummy/db/.gitkeep
|
225
226
|
- spec/dummy/doc/apipie_examples.yml
|
226
227
|
- spec/dummy/public/404.html
|
227
228
|
- spec/dummy/public/422.html
|
@@ -284,6 +285,7 @@ test_files:
|
|
284
285
|
- spec/dummy/config/initializers/session_store.rb
|
285
286
|
- spec/dummy/config/locales/en.yml
|
286
287
|
- spec/dummy/config/routes.rb
|
288
|
+
- spec/dummy/db/.gitkeep
|
287
289
|
- spec/dummy/doc/apipie_examples.yml
|
288
290
|
- spec/dummy/public/404.html
|
289
291
|
- spec/dummy/public/422.html
|
@@ -298,3 +300,4 @@ test_files:
|
|
298
300
|
- spec/dummy/public/stylesheets/.gitkeep
|
299
301
|
- spec/dummy/script/rails
|
300
302
|
- spec/spec_helper.rb
|
303
|
+
has_rdoc:
|