api_sketch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +404 -0
  9. data/Rakefile +8 -0
  10. data/api_sketch.gemspec +30 -0
  11. data/bin/api_sketch +10 -0
  12. data/lib/api_sketch/config.rb +7 -0
  13. data/lib/api_sketch/dsl.rb +213 -0
  14. data/lib/api_sketch/error.rb +2 -0
  15. data/lib/api_sketch/examples_server.rb +54 -0
  16. data/lib/api_sketch/generators.rb +87 -0
  17. data/lib/api_sketch/helpers.rb +21 -0
  18. data/lib/api_sketch/model.rb +227 -0
  19. data/lib/api_sketch/renderers.rb +48 -0
  20. data/lib/api_sketch/runner.rb +92 -0
  21. data/lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  22. data/lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  23. data/lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  24. data/lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  25. data/lib/api_sketch/templates/bootstrap/assets/images/favicon.ico +0 -0
  26. data/lib/api_sketch/templates/bootstrap/assets/javascripts/bootstrap.js +2114 -0
  27. data/lib/api_sketch/templates/bootstrap/assets/javascripts/bootstrap.min.js +6 -0
  28. data/lib/api_sketch/templates/bootstrap/assets/javascripts/docs.min.js +24 -0
  29. data/lib/api_sketch/templates/bootstrap/assets/javascripts/ie10-viewport-bug-workaround.js +22 -0
  30. data/lib/api_sketch/templates/bootstrap/assets/javascripts/jquery-1.11.1.min.js +4 -0
  31. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap-theme.css +442 -0
  32. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap-theme.css.map +1 -0
  33. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap-theme.min.css +5 -0
  34. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap.css +6203 -0
  35. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap.css.map +1 -0
  36. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/bootstrap.min.css +5 -0
  37. data/lib/api_sketch/templates/bootstrap/assets/stylesheets/dashboard.css +130 -0
  38. data/lib/api_sketch/templates/bootstrap/resource.html.erb +215 -0
  39. data/lib/api_sketch/version.rb +3 -0
  40. data/lib/api_sketch.rb +19 -0
  41. data/spec/lib/dsl_spec.rb +474 -0
  42. data/spec/spec_helper.rb +1 -0
  43. metadata +187 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6908ab17b9fdfd6d03c2a70024e302fc9e5b7860
4
+ data.tar.gz: 4444f8b4898282b779172e6111b59bbf80e586e0
5
+ SHA512:
6
+ metadata.gz: bf925a6d9b5431b0a5e9d6f63259c42227e366100a9bc51251e874e0d1424feb6caa2801a5a23640aa221cda181931590361e2355b2df5737214d182b51722a9
7
+ data.tar.gz: 6b8e5af2fd9decc7b1e1b7c75345f06cb185545dcc9075105ee4c223496a937cb297327feb9278b1c497541d8c8d84861ad39577e97052d2cf269a56d24f12b2
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ api_sketch
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.1.0 / 2015-04-12
2
+
3
+ - Add documentation
4
+ - Add API Examples server
5
+
6
+ # 0.0.1 / 2015-01-24
7
+
8
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in api_sketch.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Alexey Suhoviy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,404 @@
1
+ # Api Sketch
2
+ ------------
3
+
4
+ api_sketch gem provides you with DSL to describe and create API documentation.
5
+
6
+ It consists of three main parts:
7
+
8
+ 1. API definitions DSL
9
+ 2. Documentation generator
10
+ 3. API example responses server
11
+
12
+ ---
13
+
14
+ Installation
15
+ ------------
16
+
17
+ Include the gem in your Gemfile:
18
+
19
+ ```ruby
20
+ gem 'api_sketch'
21
+ ```
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install api_sketch
26
+
27
+ Usage
28
+ -----
29
+
30
+ Gem is bundled with the same named executable. It's supported options list is provided below.
31
+
32
+ ```
33
+ $ api_sketch -h
34
+ Usage: /bin/api_sketch (options)
35
+ -d, --debug Run in verbose mode
36
+ -i, --input DEFINITIONS Path to the folder with api definitions (required)
37
+ -o, --output DOCUMENTATION Path to the folder where generated documentation should be saved (Default is 'documentation' folder in current folder)
38
+ -s, --server Run api examples server
39
+ -p, --port PORT Api examples server port (Default is 3127)
40
+ -g, --generate Generate documentation from provided definitions
41
+ -n, --name PROJECT_NAME Name of the project. (Default is derived from DEFINITIONS folder name)
42
+ -v, --version Show version number
43
+ -h, --help Show this help
44
+ ```
45
+
46
+ ### Documentation generation
47
+
48
+ Documentaion generation command example:
49
+
50
+ ```
51
+ $ api_sketch -g -i definitions -o documentation
52
+ ```
53
+ ### API example responses server
54
+
55
+ Start API example responses server command example:
56
+
57
+ ```
58
+ $ api_sketch -s -i definitions
59
+ [2015-04-12 20:46:19] INFO WEBrick 1.3.1
60
+ [2015-04-12 20:46:19] INFO ruby 2.1.2 (2014-05-08) [x86_64-darwin13.0]
61
+ [2015-04-12 20:46:19] INFO WEBrick::HTTPServer#start: pid=5874 port=3127
62
+ ```
63
+ After this server was started response example may be accessed with this kind url:
64
+
65
+ ```
66
+ http://localhost:3127/.json?api_sketch_resource_id=users/update&api_sketch_response_context=Success
67
+ ```
68
+
69
+ ```json
70
+ {
71
+ "user":{
72
+ "id":345,
73
+ "email":"user44@email.com",
74
+ "first_name":"First name 20",
75
+ "last_name":"Last name 96",
76
+ "country":{
77
+ "name":"Ukraine",
78
+ "id":"UA"
79
+ },
80
+ "authentications":[
81
+ {
82
+ "uid":"6668-5565-3835-6085-8727",
83
+ "provider":"facebook"
84
+ }
85
+ ]
86
+ }
87
+ }
88
+ ```
89
+
90
+ `api_sketch_resource_id` and `api_sketch_response_context` parameters are used to determine which response should be returned.
91
+
92
+ Definitions
93
+ -----------
94
+
95
+ ##### Folder
96
+
97
+ API definitions files should be placed into directory with structure similar to `definitions` folder in this example. Directory may have only one file or many files and folders with files. Resurce's `namespace` is derived from this hierachical structure.
98
+
99
+ ```
100
+ definitions
101
+ ├── places.rb
102
+ ├── users
103
+ │   └── points.rb
104
+ └── users.rb
105
+ ```
106
+ ##### DSL
107
+
108
+ Definitions DSL is writen in ruby. It consists of special keywords that are used to describe API endpoint resource's request options, url, and list of possible responses.
109
+
110
+ Here is dummy example of `resource` definition that includes most part of DSL syntax.
111
+
112
+ `action` and `namespace` both form resource ID that should be unique. For this current case resource ID would be `users/update`.
113
+
114
+ If `namespace` is omitted than it would be derived from folders structure and file name where this defintion is placed in. So, for example if definition is placed inside `users/points.rb` than it's namespace is `users/points`.
115
+
116
+ DSL provides `path`, `http_method`, `headers`, `parameters` keywords for request data definition. Parameters could be placed at `query` and `body` containers. Both of them could have `:array` or `:document` structure.
117
+
118
+ Supported attribute types are: `integer`, `string`, `float`, `boolean`, `datetime`, `timestamp`, `document`, `array`
119
+
120
+ Each attribute should have name, could have `description`, `example` value, could be `required`.
121
+
122
+ `example` keyword accepts callable blocks or just some simple values. Callable blocks may give new value each time `example_value` is requested.
123
+
124
+ Array and query attribute types have `content` keyword where their contents are placed in.
125
+
126
+ Each `resource` could have many `responses` with different `context`. For example succesful one and few with different errors. Especially for `responses` it is better to provide detailed `example` values as they could be used as responses by examples server.
127
+
128
+ Resource `parameters` section's syntax it the same as for `resource` request parameters.
129
+
130
+ ```ruby
131
+ resource "Update user profile" do # Resource name
132
+ action "update"
133
+ namespace "users"
134
+ description "Authenticated user could update his profile fields and password"
135
+ path "/api/users/me.json" # Server path where this endpoint would be processed
136
+ http_method "PUT" # http request method
137
+ format "json" # response format
138
+
139
+ headers do
140
+ add "Authorization" do
141
+ value "Token token=:token_value"
142
+ description ":token_value - is an authorization token value"
143
+ example { (:A..:z).to_a.shuffle[0,16].join }
144
+ required true
145
+ end
146
+
147
+ add "X-Test" do
148
+ value "Test=:perform_test"
149
+ description ":perform_test - test boolean value"
150
+ example true
151
+ end
152
+ end
153
+
154
+ parameters do
155
+ # parametes could be query and body
156
+ query :document do
157
+ string "hello_message" do
158
+ description "some message"
159
+ end
160
+
161
+ integer "repeat_times" do
162
+ description "times to repeat hello message"
163
+ end
164
+ end
165
+
166
+ query :document do
167
+ integer "page" do
168
+ description "page number"
169
+ required false
170
+ default 1
171
+ end
172
+
173
+ integer "per_page" do
174
+ description "items per page amount"
175
+ required false
176
+ default 25
177
+ end
178
+
179
+ string "name" do
180
+ description "place name"
181
+ required true
182
+ end
183
+
184
+ float "range" do
185
+ description "search range in km"
186
+ required false
187
+ example { rand(100) + rand.round(2) }
188
+ end
189
+
190
+ datetime "start_at" do
191
+ description "start at datetime"
192
+ required false
193
+ example { Time.now.to_s }
194
+ end
195
+
196
+ timestamp "seconds" do
197
+ description "seconds today"
198
+ example { Time.now.to_i }
199
+ end
200
+
201
+ array "place_ids" do
202
+ description "user's places ids"
203
+ required false
204
+ content do
205
+ integer do
206
+ description "hello number"
207
+ end
208
+ string do
209
+ description "more text here"
210
+ end
211
+ document do
212
+ content do
213
+ boolean "is_it_true" do
214
+ end
215
+ end
216
+ end
217
+ document do
218
+ description "some useless data :)"
219
+ content do
220
+ string "test" do
221
+ description "test string"
222
+ end
223
+ document "keys" do
224
+ content do
225
+ integer "sum" do
226
+ end
227
+ string "details text" do
228
+ end
229
+ end
230
+ end
231
+
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ body :document do
239
+ document "user" do
240
+ description "user's parameters fields"
241
+ required true
242
+ content do
243
+ string "email" do
244
+ description "user's email value"
245
+ end
246
+ string "password" do
247
+ description "user's profile password"
248
+ end
249
+ string "first_name" do
250
+ description "user's first name"
251
+ end
252
+ string "last_name" do
253
+ description "user's last name"
254
+ end
255
+ string "country_locode" do
256
+ example { ["US", "UA"].sample }
257
+ description "Country location code"
258
+ end
259
+
260
+ document "stats" do
261
+ content do
262
+ timestamp "login_at" do
263
+ description "last login timestamp"
264
+ example { Time.now.to_i }
265
+ end
266
+
267
+ integer "login_count" do
268
+ description "login count"
269
+ example { rand(10000) }
270
+ end
271
+
272
+ string "rank" do
273
+ description "users rank"
274
+ example { ["Junior", "Middle", "Senior"].sample }
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ responses do
284
+ context "Success" do
285
+ http_status :ok # 200
286
+
287
+ parameters do
288
+ body :document do
289
+ document "user" do
290
+ content do
291
+ integer "id" do
292
+ description "User's ID"
293
+ end
294
+ string "email" do
295
+ description "user's email value"
296
+ example { "user#{rand(100)}@email.com" }
297
+ end
298
+ string "first_name" do
299
+ description "user's first name"
300
+ example { "First name #{rand(100)}" }
301
+ end
302
+ string "last_name" do
303
+ description "user's last name"
304
+ example { "Last name #{rand(100)}" }
305
+ end
306
+ document "country" do
307
+ content do
308
+ string "name" do
309
+ description "Country name"
310
+ example { ["USA", "Ukraine", "Poland"].sample }
311
+ end
312
+ string "id" do
313
+ example :location_code
314
+ description "Country ID (Location code)"
315
+ example { ["US", "UA", "PL"].sample }
316
+ end
317
+ end
318
+ end
319
+ array "authentications" do
320
+ content do
321
+ document do
322
+ content do
323
+ string "uid" do
324
+ description "user's id at social network"
325
+ example { 5.times.map { 4.times.map { rand(10).to_s }.join }.join("-") }
326
+ end
327
+ string "provider" do
328
+ example { "facebook" }
329
+ description "user's social network type"
330
+ end
331
+ end
332
+ end
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end
339
+ end
340
+
341
+ context "Failure" do
342
+ http_status :bad_request # 400
343
+
344
+ parameters do
345
+ body :document do
346
+ document "error" do
347
+ content do
348
+ string "message" do
349
+ description "Error description"
350
+ example { "Epic fail at your parameters" }
351
+ end
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
359
+ ```
360
+
361
+ For more detailed DSL features examples check DSL test files at spec folder.
362
+
363
+ TODO
364
+ ----
365
+
366
+ - Clean genrated documentation html template css, javascripts. Remove useless classes, html, etc.
367
+ - Add local javascript search feature at generated html docs
368
+ - Add API index page similar to [Foursquare API docs](https://developer.foursquare.com/docs/)
369
+ - Improve documentation, add more examples
370
+ - Add more documentation templates. For example PDF, curl, some other html styles, etc. It should be configurable as api_sketch command line option. This might be made as some separate extensions gem. There also could be generators for some specific framework api controllers structure scaffold generators.
371
+ - Put all generated pages data into `{output_folder}/docs` directory. Left `assets` directory outside since it may clash with generated files/folders names.
372
+ - API examples server also should support endpoint search by request `path` & `http_method` like normal api server does.
373
+ - Deal with query body at responses (For example redirects may have query body)
374
+ - Validate HTTP method with path, http method and action unique composition
375
+ - Add other request/response types like plaintext, xml, etc (should be supprted both at generator and server)
376
+ - Add realtime viewable page with log for this api examples server application to let client side developers see what data they have sent and how server received it
377
+ - Add more validations to models.
378
+ - Add more specs and tests.
379
+ - Add `shared_block "shared block name"` (definition keyword) search keyword by it's to blocks. Maybe `uses_shared_block "shared block name"`. Maybe shared blocks should be placed into special directory at definitions to be loaded before all examples
380
+ - Add more complex example values autogeneration for API examples server. Derive values from key names. For example string "email" should have some email value as response example.
381
+ - Add `api_sketch_response_array_elements_count` for responses server. It should generate responses with provided array elements counts. If array contains different type values than each type of these elements should be placed to response multiple times.
382
+ - rDoc documentation for code.
383
+
384
+ Contributing
385
+ ------------
386
+
387
+ 1. Fork it ( https://github.com/suhovius/api_sketch/fork )
388
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
389
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
390
+ 4. Push to the branch (`git push origin my-new-feature`)
391
+ 5. Create a new Pull Request
392
+
393
+ Inspirations
394
+ ------------
395
+ - [Calamum](https://github.com/malachheb/calamum)
396
+ - [Apiary](http://apiary.io/blueprint)
397
+ - [IO Docs](https://github.com/mashery/iodocs)
398
+ - [Swagger](https://developers.helloreverb.com/swagger)
399
+
400
+
401
+ License
402
+ -------
403
+
404
+ ApiSketch is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
8
+
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ require File.expand_path('../lib/api_sketch/version', __FILE__)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "api_sketch"
6
+ spec.version = ApiSketch::VERSION
7
+ spec.authors = ["Alexey Suhoviy"]
8
+ spec.email = ["martinsilenn@gmail.com"]
9
+ spec.summary = %q{API Prototyping and API Documentation Tool}
10
+ spec.description = %q{Gem provides DSL for API documentation generation and API request examples server}
11
+
12
+ spec.homepage = "https://github.com/suhovius/api_sketch"
13
+
14
+ spec.license = "MIT"
15
+ spec.post_install_message = "Thanks for installing!"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'mixlib-cli'
23
+ spec.add_dependency 'mixlib-config'
24
+ spec.add_dependency 'rack'
25
+ spec.add_dependency 'rack-contrib'
26
+
27
+ spec.add_development_dependency "bundler"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "rspec"
30
+ end
data/bin/api_sketch ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'api_sketch'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'api_sketch'
8
+ end
9
+
10
+ ApiSketch::Runner.new.run
@@ -0,0 +1,7 @@
1
+ require 'mixlib/config'
2
+
3
+ # Provides a class-based configuration object.
4
+ # See https://github.com/opscode/mixlib-config
5
+ class ::ApiSketch::Config
6
+ extend Mixlib::Config
7
+ end