apipony 0.0.9 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7456f0b6bcd79edd941bfba6e1db27e3c0b94f00
4
- data.tar.gz: 08f3bb7e4dfdb5a590a78f8ed2be46b5a475e873
3
+ metadata.gz: c2763c3a557bf3218d2e22427926fa6ccac254a8
4
+ data.tar.gz: 4684d6258f0a056d13b33dc189c48cb9de433da9
5
5
  SHA512:
6
- metadata.gz: d8a9c0b84b6da18245b2dc3187a63ee8ad30de426d45a4fd47f2ee7e384405dd1e4a2665358f0df09b214804157afaa09d0a5c6c2c2410120782c281bfdb79ff
7
- data.tar.gz: 4d7d48df1304b3e316adc35e410ae44f040195127e9dfcd4dca971c6c2dcd806d737ee0ceb31a68c1fd3173b1884333da21b02989c97a252f8390ce8fc45c2c1
6
+ metadata.gz: aa6373f944c15dfcb256dd1a22889426bd6936698733db49285a25d41b5a3eca71125e0f52a683fcbcd16889fae92ca02ed12169027ff01459c6d3fc78cd5f7b
7
+ data.tar.gz: a19bc419ba2fc6bcf86a761bf1710070fc7193ebd65307b68778e877ed2a211b88131a76092633fc405e959c7af7ac25798ea2c199fb0321272dfe0e00da9503
data/README.md CHANGED
@@ -6,246 +6,124 @@
6
6
 
7
7
  Ruby DSL to create Rails API documentation from your application.
8
8
 
9
-
10
- ## Getting started
9
+ ## Getting Started
11
10
  * Add `gem 'apipony'` to Gemfile
12
11
  * `bundle install`
13
12
  * `rails g apipony:install`
14
- * Now you can edit your documentation in `config/initializers/apipony.rb`
13
+ * Edit your documentation in `config/initializers/apipony.rb`
15
14
 
15
+ ![Example](https://raw.githubusercontent.com/droptheplot/apipony/master/preview.png)
16
16
 
17
- ## How it works
18
- DSL example:
17
+ ## Example
19
18
 
20
19
  ```ruby
21
20
  Apipony::Documentation.define do
22
- config do |c|
23
- c.title = 'Apipony Documentation'
24
- c.base_url = '/api/v1'
21
+ configure do
22
+ title 'API Documentation'
23
+ base_url '/api/v1'
25
24
  end
26
25
 
27
26
  section 'Ponies' do
28
- endpoint :get, '/ponies' do |e|
29
- e.description = 'Find ponies'
27
+ endpoint :get, '/ponies' do
28
+ description 'List ponies.'
30
29
 
31
30
  request_with do
32
- param :name, example: 'applejack', required: true
33
- end
31
+ headers do
32
+ {
33
+ 'Accept': 'application/json'
34
+ }
35
+ end
34
36
 
35
- response_with 200 do
36
- attribute :name, type: :string, example: 'applejack'
37
- attribute :kind, type: :string, example: 'earth'
38
- attribute :sex, type: :string, example: 'female'
39
- attribute :occupation, type: :string, example: 'farmer'
37
+ param :name, required: true, description: 'Name of pony.',
38
+ example: :fluttershy
40
39
  end
41
- end
42
- end
43
- end
44
- ```
45
-
46
-
47
- ## Features
48
40
 
49
- ### Response Attribute Documentation
50
- Apipony lets you provide further documentation about the attributes in your
51
- API's responses. Simply create a new `attribute` inside a `response_with` block.
52
- These attributes can even have nested sub-attributes, for documentation of
53
- more complex object graphs.
54
-
55
- ```ruby
56
- Apipony::Documentation.define do
57
- section "Species" do
58
- endpoint 'get', '/species/:id' do |e|
59
- e.description = "Get information about a species"
60
- response_with 200 do
61
- example do
62
- set :body, {
63
- name: "Unicorn",
64
- is_pony: true,
65
- biology: {
66
- has_horn: true,
67
- has_wings: false
41
+ response_with do
42
+ body do
43
+ [
44
+ {
45
+ name: 'Fluttershy',
46
+ kind: 'Pegasus'
68
47
  }
69
- }
70
- end
71
- attribute :name, type: :string
72
- attribute :is_pony, type: :bool,
73
- description: "Is this species a type of pony?"
74
- attribute :biology do
75
- attribute :has_horn, type: :bool
76
- attribute :has_wings, type: :bool
48
+ ]
77
49
  end
78
50
  end
79
51
  end
80
- end
81
- end
82
- ```
83
52
 
84
- ### Enum Attributes
85
- Your API may have some fields that can be picked from a pre-defined set of
86
- values. You can document those values by using an enum attribute.
53
+ endpoint :post, '/ponies' do
54
+ description 'Create new pony.'
87
55
 
88
- ```ruby
89
- Apipony::Documentation.define do
90
- section "Ponies" do
91
- endpoint "get", "/ponies/:id" do |e|
92
- e.description = "Information about a pony"
93
- example do
94
- set :body, {
95
- name: "Applejack",
96
- sex: "female",
97
- kind: :earth,
98
- occupation: :farmer
99
- }
100
- end
101
-
102
- attribute :kind, type: :enum do
103
- choice :earth, description: "A pony with no wings or horn"
104
- choice :unicorn, description: "A pony with a horn"
105
- choice :pegasus, description: "A pony with wings"
106
- choice :alicorn,
107
- description: "A pony with wings and a horn. Indicates royalty."
56
+ request_with do
57
+ param :name, required: true, example: :fluttershy
58
+ param :kind, example: :pegasus
59
+ param :sex, required: true, example: :female
60
+ param :occupation, example: :caretaker,
61
+ description: 'What this pony do for living.'
108
62
  end
109
63
  end
110
- end
111
- end
112
- ```
113
64
 
114
- ### Example Generation
115
- When describing attributes, you can provide an optional `example:` parameter.
116
- If included, this will be used to generate the example response in the
117
- documentation.
65
+ endpoint :put, '/ponies/:id' do
66
+ description 'Update pony by id.'
118
67
 
119
- ```ruby
120
- Apipony::Documentation.define do
121
- section "Ponies" do
122
- endpoint "get", "/ponies/:id" do |e|
123
- response_with 200 do
124
- attribute :name, type: :string, example: "Applejack"
125
- # Enum members automatically select the first choice
126
- attribute :kind, type: :enum do
127
- choice :earth
128
- choice :pegasus
129
- choice :unicorn
130
- choice :alicorn
131
- end
68
+ request_with do
69
+ param :name
70
+ param :kind
71
+ param :sex
72
+ param :occupation
132
73
  end
133
74
  end
134
75
 
135
- endpoint "get", "/ponies/" do |e|
136
- # Automatic serialization of arrays is supported
137
- response_with 200, array: true do
138
- attribute :name, type: :string, example: "Applejack"
139
- attribute :id, type: :integer, example: 10
140
- end
76
+ endpoint :delete, '/ponies/:id' do
77
+ description 'Delete pony by id.'
141
78
  end
142
79
  end
143
- end
144
- ```
145
-
146
- `GET /ponies/:id` will now have the example of:
147
-
148
- ```json
149
- {
150
- "name": "Applejack",
151
- "kind": "Earth"
152
- }
153
- ```
154
-
155
- `GET /ponies/` will have the example of:
156
-
157
- ```json
158
- [
159
- {
160
- "name": "Applejack",
161
- "id": 10
162
- }
163
- ]
164
- ```
165
80
 
166
- ### Predefined Subtypes
167
- Sometimes, when building an API, it can be useful to store data in a common
168
- format. Apipony lets you define this common format once, then use it multiple
169
- times. Check it out:
81
+ section 'Places' do
82
+ endpoint :get, '/places' do
83
+ description 'List places.'
170
84
 
171
- ```ruby
172
- Apipony::Documentation.define do
173
- subtype :pony_stub do
174
- attribute :name, type: :string
175
- attribute :id, type: :integer
176
- end
85
+ response_with do
86
+ status 200
177
87
 
178
- section "Ponies" do
179
- endpoint 'get', '/ponies/:id' do |e|
180
- e.description = "Find a pony with a given name"
181
- request_with do
182
- params :id, example: 10, required: true
183
- end
184
-
185
- response_with 200 do
186
- example do
187
- set :body, {
188
- :name => :applejack,
189
- :type => :earth,
190
- :sex => :female,
191
- :occupation => :farmer,
192
- :friends => [
193
- {name: "Twilight Sparkle", id: 1},
194
- {name: "Pinkie Pie", id: 2},
195
- {name: "Rainbow Dash", id: 3},
196
- {name: "Rarity", id: 4},
197
- {name: "Fluttershy", id: 5}
198
- ]
199
- }
88
+ body do
89
+ [
90
+ {
91
+ name: 'Equestria'
92
+ },
93
+ {
94
+ name: 'Ponyville'
95
+ }
96
+ ]
200
97
  end
201
- attribute :name, type: :string
202
- attribute :kind, type: :enum do
203
- choice :alicorn
204
- choice :earth
205
- choice :unicorn
206
- choice :pegasus
207
98
  end
208
- attribute :friends, type: :pony_stub, array: true
209
- attribute :occupation, type: :string
210
99
  end
211
- end
212
100
 
213
- section "Locations" do
214
- endpoint 'get', '/locations/:id' do |e|
215
- e.description = "Information about a location"
216
- response_with 200 do
217
- example do
218
- set :body, {
219
- :name => "Crystal Empire",
220
- :population => 107770,
221
- :rulers => [
222
- {
223
- name: "Shining Armor",
224
- id: 50
225
- },
226
- {
227
- name: "Princess Cadence",
228
- id: 90001
229
- }
230
- ]
101
+ endpoint :get, '/places/:id' do
102
+ response_with do
103
+ status 200
104
+
105
+ body do
106
+ {
107
+ name: 'Crystal Empire',
108
+ population: 107706
231
109
  }
232
110
  end
233
- attribute :name, type: :string
234
- attribute :population, type: :integer
235
- attribute :rulers, type: :pony_stub, array: true
236
111
  end
237
112
  end
238
113
  end
239
114
  end
240
115
  ```
241
116
 
242
- Now, the `friends` attribute of `GET /ponies/:id` and the `rulers` attribute of
243
- `GET /locations/:id` will reference a common subtype on the generated
244
- documentation.
117
+ By default documentation available here `/apipony`. But you can always change it in `config/routes.rb`.
245
118
 
119
+ ## Contributing
246
120
 
247
- Generated documentation example:
121
+ 1. Fork it (https://github.com/droptheplot/apipony/fork)
122
+ 2. Create your feature branch (git checkout -b my-new-feature)
123
+ 3. Commit your changes (git commit -am 'Add some feature')
124
+ 4. Push to the branch (git push origin my-new-feature)
125
+ 5. Create new Pull Request
248
126
 
249
- ![Example](https://raw.githubusercontent.com/droptheplot/apipony/master/preview.png)
127
+ ## License
250
128
 
251
- By default documentation available here `/apipony`. But you can always change it in `config/routes.rb`.
129
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -7,17 +7,13 @@ end
7
7
 
8
8
  require 'rdoc/task'
9
9
 
10
- YARD::Rake::YardocTask.new(:doc) do |doc|
11
- end
12
-
13
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
14
- load 'rails/tasks/engine.rake'
10
+ YARD::Rake::YardocTask.new(:doc) {}
15
11
 
12
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
16
13
 
14
+ load 'rails/tasks/engine.rake'
17
15
  load 'rails/tasks/statistics.rake'
18
16
 
19
-
20
-
21
17
  Bundler::GemHelper.install_tasks
22
18
 
23
19
  require 'rake/testtask'
@@ -29,5 +25,4 @@ Rake::TestTask.new(:test) do |t|
29
25
  t.verbose = false
30
26
  end
31
27
 
32
-
33
28
  task default: :test
@@ -5,14 +5,14 @@ $light_color: #eee;
5
5
  $brand_color: #5e147d;
6
6
 
7
7
  // Method colors
8
- $get-color: #1abc9c;
9
- $post-color: #3498db;
10
- $put-color: #2980d9;
11
- $delete-color: #c0392b;
8
+ $get_color: #1abc9c;
9
+ $post_color: #3498db;
10
+ $put_color: #2980d9;
11
+ $delete_color: #c0392b;
12
12
 
13
13
  // Misc. values
14
- $transition-time: 200ms;
15
- $mobile-width: 900px;
14
+ $transition_time: 200ms;
15
+ $mobile_width: 900px;
16
16
 
17
17
 
18
18
  *, *::before, *::after {
@@ -57,7 +57,7 @@ h2 {
57
57
  }
58
58
 
59
59
  h3 {
60
- padding-top: 10px;
60
+ margin-bottom: 20px;
61
61
  font-size: 17px;
62
62
  line-height: 16px;
63
63
  }
@@ -96,7 +96,7 @@ ul {
96
96
  display: flex;
97
97
  flex-flow: row nowrap;
98
98
 
99
- @media all and (max-width: $mobile-width) {
99
+ @media all and (max-width: $mobile_width) {
100
100
  flex-flow: row wrap;
101
101
  }
102
102
  }
@@ -105,7 +105,7 @@ ul {
105
105
  flex: 1 80px;
106
106
  margin-right: 40px;
107
107
 
108
- @media all and (max-width: $mobile-width) {
108
+ @media all and (max-width: $mobile_width) {
109
109
  flex: 1 100%;
110
110
  margin-bottom: 30px;
111
111
  }
@@ -120,28 +120,27 @@ ul {
120
120
  .main-col {
121
121
  flex: 8;
122
122
 
123
- @media all and (max-width: $mobile-width) {
123
+ @media all and (max-width: $mobile_width) {
124
124
  flex: 1 100%;
125
125
  }
126
126
  }
127
127
 
128
128
  header {
129
- background: $brand_color;
130
129
  height: 60px;
131
130
  line-height: 60px;
131
+ border-bottom: 1px solid $light_color;
132
132
 
133
133
  .title {
134
134
  font-weight: bold;
135
- font-size: 20px;
136
- color: #fff;
135
+ font-size: 17px;
137
136
  }
138
137
 
139
138
  .back {
140
139
  float: right;
141
- color: #fff;
142
140
  opacity: 0.7;
143
141
  font-size: 12px;
144
- transition: $transition-time opacity;
142
+ transition: $transition_time opacity;
143
+ margin-left: auto;
145
144
 
146
145
  &:hover {
147
146
  opacity: 1;
@@ -163,7 +162,7 @@ footer {
163
162
 
164
163
  a {
165
164
  color: $medium_color;
166
- transition: $transition-time color;
165
+ transition: $transition_time color;
167
166
 
168
167
  &:hover {
169
168
  color: $dark-color;
@@ -185,23 +184,23 @@ footer {
185
184
  margin-bottom: 40px;
186
185
  }
187
186
 
188
- .description {
189
- font-size: 12px;
190
- color: $medium_color;
191
- padding-top: 20px;
192
- font-weight: normal;
193
- }
194
-
195
187
  .response, .request {
196
- padding-top: 20px;
188
+ padding-bottom: 20px;
197
189
 
198
190
  .code {
199
191
  padding: 8px 10px 10px;
200
- font-size: 14px;
192
+ font-size: 12px;
201
193
  border-radius: 0 0 3px 3px;
202
194
  }
203
195
  }
204
196
  }
197
+
198
+ > .description, .endpoint > .description {
199
+ font-size: 12px;
200
+ color: $medium_color;
201
+ padding-bottom: 20px;
202
+ font-weight: normal;
203
+ }
205
204
  }
206
205
 
207
206
  .panel {
@@ -230,23 +229,23 @@ footer {
230
229
  background-color: $medium_color;
231
230
 
232
231
  &.get {
233
- background-color: $get-color;
232
+ background-color: $get_color;
234
233
  }
235
234
 
236
235
  &.post {
237
- background-color: $post-color;
236
+ background-color: $post_color;
238
237
  }
239
238
 
240
239
  &.put {
241
- background-color: $put-color;
240
+ background-color: $put_color;
242
241
  }
243
242
 
244
243
  &.delete {
245
- background-color: $delete-color;
244
+ background-color: $delete_color;
246
245
  }
247
246
  }
248
247
 
249
- .parameters, .attributes {
248
+ .parameter {
250
249
  font-size: 12px;
251
250
 
252
251
  .name {
@@ -266,6 +265,12 @@ footer {
266
265
  color: $medium_color;
267
266
  }
268
267
  }
268
+
269
+ > .description {
270
+ .example {
271
+ color: $medium_color;
272
+ }
273
+ }
269
274
  }
270
275
 
271
276
  .table {
@@ -277,72 +282,3 @@ footer {
277
282
  }
278
283
  }
279
284
  }
280
-
281
- .attribute-container {
282
- display: flex;
283
- flex-flow: column nowrap;
284
-
285
- .attribute {
286
- display: flex;
287
- flex-flow: row nowrap;
288
- align-items: inherit;
289
- justify-content: flex-start;
290
-
291
- > div {
292
- padding: 4px 10px;
293
- }
294
-
295
- .attribute-type {
296
- flex: 1 1 60px;
297
- }
298
-
299
- .attribute-name {
300
- flex: 2 1 0;
301
- min-width: 90px;
302
- }
303
-
304
- .attribute-description {
305
- flex: 8 1 0;
306
- }
307
- }
308
-
309
- ul {
310
- margin: 8px 10px;
311
- border: 1px solid #e1e1e1;
312
- border-radius: 3px;
313
-
314
- li {
315
- list-style: none;
316
- margin: 10px 0;
317
- padding: 0 12px;
318
- }
319
- }
320
- }
321
-
322
- .attribute-enum-member {
323
- display: flex;
324
- flex-flow: row nowrap;
325
-
326
- .title {
327
- border-bottom: 1px solid darken($light_color, 5%);
328
- padding: 10px;
329
- font-size: 11px;
330
- font-weight: bold;
331
- }
332
-
333
- .attribute-enum-member-name {
334
- font-weight: 400;
335
- margin-right: 10px;
336
- min-width: 60px;
337
- flex: 1 1 0;
338
- color: $brand_color;
339
- }
340
-
341
- .attribute-enum-member-description {
342
- flex: 7 1 0;
343
- }
344
- }
345
-
346
- .subtype {
347
- margin-bottom: 25px;
348
- }
@@ -1,8 +1,13 @@
1
1
  <header>
2
2
  <div class="container">
3
- <%= link_to @documentation.title, root_path, class: 'title' %>
4
- <% if main_app.root_path %>
5
- <%= link_to 'Back to site', main_app.root_path, class: 'back' %>
6
- <% end %>
3
+ <div class="row">
4
+ <%= link_to @documentation.data.title, root_path, class: 'title' %>
5
+ <% if main_app.root_path %>
6
+ <%= link_to main_app.root_path, class: 'back' do %>
7
+ <i class='fa fa-home'></i>
8
+ Home
9
+ <% end %>
10
+ <% end %>
11
+ </div>
7
12
  </div>
8
13
  </header>
@@ -1,11 +1,19 @@
1
1
  <div class="request">
2
2
  <h4>Request&#58;</h4>
3
- <% if endpoint.request.params %>
3
+
4
+ <% if endpoint.request.data.headers %>
5
+ <div class="panel">
6
+ <div class="title">Headers</div>
7
+ <pre class="code"><%= JSON.pretty_generate(endpoint.request.data.headers) %></pre>
8
+ </div>
9
+ <% end %>
10
+
11
+ <% if endpoint.request.data.params %>
4
12
  <div class="panel">
5
13
  <div class="title">Parameters</div>
6
14
  <table class="table">
7
- <% endpoint.request.params.each do |param| %>
8
- <tr class="parameters">
15
+ <% endpoint.request.data.params.each do |param| %>
16
+ <tr class="parameter">
9
17
  <td class="name">
10
18
  <%= param.name %>
11
19
  </td>
@@ -19,19 +27,17 @@
19
27
  <i class="fa fa-square-o" title="Optional"></i>
20
28
  <% end %>
21
29
  </td>
22
- <td class="example">
23
- <%= param.example %>
30
+ <td class="description">
31
+ <%= param.description %>
32
+ <% if param.example %>
33
+ <span class="example">
34
+ (example: <strong><%= param.example %></strong>)
35
+ </span>
36
+ <% end %>
24
37
  </td>
25
38
  </tr>
26
39
  <% end %>
27
40
  </table>
28
41
  </div>
29
42
  <% end %>
30
-
31
- <% if endpoint.request.headers %>
32
- <div class="panel">
33
- <div class="title">Headers</div>
34
- <pre class="code"><%= JSON.pretty_generate(endpoint.request.headers) %></pre>
35
- </div>
36
- <% end %>
37
43
  </div>