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 +4 -4
- data/README.md +71 -193
- data/Rakefile +3 -8
- data/app/assets/stylesheets/apipony/styles.scss +35 -99
- data/app/views/apipony/application/_header.html.erb +9 -4
- data/app/views/apipony/application/_request.html.erb +18 -12
- data/app/views/apipony/application/_response.html.erb +9 -18
- data/app/views/apipony/application/index.html.erb +8 -21
- data/app/views/layouts/apipony/application.html.erb +1 -1
- data/lib/apipony/documentation.rb +33 -37
- data/lib/apipony/endpoint.rb +47 -40
- data/lib/apipony/engine.rb +0 -1
- data/lib/apipony/parameter.rb +21 -9
- data/lib/apipony/request.rb +27 -20
- data/lib/apipony/response.rb +22 -40
- data/lib/apipony/section.rb +26 -18
- data/lib/apipony/shared/description.rb +11 -0
- data/lib/apipony/shared/headers.rb +11 -0
- data/lib/apipony/version.rb +1 -3
- data/lib/apipony.rb +3 -20
- data/lib/generators/apipony/install/templates/initializer.rb +58 -41
- data/lib/generators/apipony/install_generator.rb +9 -3
- metadata +21 -9
- data/app/views/apipony/application/_attribute.html.erb +0 -42
- data/lib/apipony/base.rb +0 -7
- data/lib/apipony/example_response.rb +0 -9
- data/lib/apipony/response_attribute.rb +0 -130
@@ -1,30 +1,21 @@
|
|
1
1
|
<div class="response">
|
2
|
-
<h4>Response: <%= response.status %></h4>
|
3
|
-
<% if response.
|
2
|
+
<h4>Response: <%= response.data.status %></h4>
|
3
|
+
<% if response.data? %>
|
4
4
|
<div class="response-example">
|
5
5
|
<%# This is kind of fancy for no reason but whatever %>
|
6
|
-
<% if response.
|
7
|
-
<div class="
|
8
|
-
|
6
|
+
<% if response.data.headers %>
|
7
|
+
<div class="panel">
|
8
|
+
<div class="title">Headers</div>
|
9
|
+
<pre class="code hljs json"><%= JSON.pretty_generate(response.data.headers) %></pre>
|
10
|
+
</div>
|
9
11
|
<% end %>
|
10
12
|
|
11
|
-
<% if response.
|
13
|
+
<% if response.data.body %>
|
12
14
|
<div class="panel">
|
13
15
|
<div class="title">Body</div>
|
14
|
-
<pre class="code hljs json"><%= JSON.pretty_generate(response.
|
16
|
+
<pre class="code hljs json"><%= JSON.pretty_generate(response.data.body) %></pre>
|
15
17
|
</div>
|
16
18
|
<% end %>
|
17
19
|
</div>
|
18
20
|
<% end %>
|
19
|
-
|
20
|
-
<% if response.attributes.size > 0 %>
|
21
|
-
<div class="panel">
|
22
|
-
<div class="title">Attributes</div>
|
23
|
-
<div class="table">
|
24
|
-
<div class="attributes">
|
25
|
-
<%= render partial: 'attribute', collection: response.attributes, as: :attribute %>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
</div>
|
29
|
-
<% end %>
|
30
21
|
</div>
|
@@ -11,13 +11,18 @@
|
|
11
11
|
<% @documentation.sections.each do |section| %>
|
12
12
|
<div class="section">
|
13
13
|
<h2 id="<%= section.title %>"><%= section.title %></h2>
|
14
|
+
<% if section.data.description %>
|
15
|
+
<div class="description">
|
16
|
+
<%= section.data.description %>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
14
19
|
<% section.endpoints.each do |endpoint| %>
|
15
20
|
<div class="endpoint" id="<%= endpoint.id %>">
|
16
21
|
<h3><%= render "method", endpoint: endpoint %></h3>
|
17
22
|
|
18
|
-
<% if endpoint.description %>
|
23
|
+
<% if endpoint.data.description %>
|
19
24
|
<div class="description">
|
20
|
-
<%= endpoint.description %>
|
25
|
+
<%= endpoint.data.description %>
|
21
26
|
</div>
|
22
27
|
<% end %>
|
23
28
|
|
@@ -27,31 +32,13 @@
|
|
27
32
|
<% end %>
|
28
33
|
|
29
34
|
<% if endpoint.response %>
|
30
|
-
<%= render "response", response: endpoint.response %>
|
35
|
+
<%= render "response", response: endpoint.response %>
|
31
36
|
<% end %>
|
32
37
|
<% end %>
|
33
38
|
</div>
|
34
39
|
<% end %>
|
35
40
|
</div>
|
36
41
|
<% end %>
|
37
|
-
|
38
|
-
<div id="defined_subtypes">
|
39
|
-
<% @documentation.subtypes.each do |name, type| %>
|
40
|
-
<div class="subtype" id="subtype-<%= name %>">
|
41
|
-
<h4><%= name %></h4>
|
42
|
-
<div class="panel">
|
43
|
-
<div class="title">Attributes</div>
|
44
|
-
<div class="table">
|
45
|
-
<div class="attributes">
|
46
|
-
<%= render partial: "attribute",
|
47
|
-
collection: type.attributes,
|
48
|
-
as: :attribute %>
|
49
|
-
</div>
|
50
|
-
</div>
|
51
|
-
</div>
|
52
|
-
</div>
|
53
|
-
<% end %>
|
54
|
-
</div>
|
55
42
|
</div>
|
56
43
|
</div>
|
57
44
|
</div>
|
@@ -1,45 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
1
|
+
# Top-level class for the DSL
|
2
|
+
module Apipony
|
3
|
+
class Documentation
|
4
|
+
class << self
|
5
|
+
attr_accessor :title, :base_url, :sections
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@base_url = ''
|
7
|
+
def define(&block)
|
8
|
+
@title = 'API Documentation'
|
9
|
+
@sections = []
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
##
|
15
|
-
# @return [Hash<String, ApiPony::ResponseAttribute] a hash of each subype.
|
16
|
-
# keys are the names of the subtype, values are the attribute object that
|
17
|
-
# defines it
|
18
|
-
def subtypes
|
19
|
-
Apipony::ResponseAttribute.defined_subtypes
|
20
|
-
end
|
11
|
+
instance_eval(&block)
|
12
|
+
end
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
14
|
+
# Start a new section.
|
15
|
+
# Sections are logically separated on the display page.
|
16
|
+
def section(title, &block)
|
17
|
+
@sections << Apipony::Section.new(title, &block)
|
18
|
+
end
|
28
19
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
20
|
+
# Configure API pony with the DSL
|
21
|
+
def configure(&block)
|
22
|
+
instance_eval(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def title(value)
|
26
|
+
@title = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def base_url(value)
|
30
|
+
@base_url = value
|
31
|
+
end
|
38
32
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
def data
|
34
|
+
OpenStruct.new(
|
35
|
+
title: @title,
|
36
|
+
base_url: @base_url
|
37
|
+
)
|
38
|
+
end
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
data/lib/apipony/endpoint.rb
CHANGED
@@ -1,49 +1,56 @@
|
|
1
1
|
##
|
2
2
|
# Model a response endpoint.
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@url = set_base_url(url)
|
22
|
-
|
23
|
-
instance_eval(&block) if block_given?
|
24
|
-
end
|
3
|
+
module Apipony
|
4
|
+
class Endpoint
|
5
|
+
include Apipony::Shared::Description
|
6
|
+
##
|
7
|
+
# What HTTP verb to use to access this endpoint
|
8
|
+
attr_accessor :method
|
9
|
+
##
|
10
|
+
# The URl of this endpoint
|
11
|
+
attr_accessor :url
|
12
|
+
|
13
|
+
attr_accessor :response, :request
|
14
|
+
|
15
|
+
def initialize(method, url, &block)
|
16
|
+
@method = method
|
17
|
+
@url = build_url(url)
|
18
|
+
|
19
|
+
instance_eval(&block) if block_given?
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
##
|
23
|
+
# DSL method to start describing a response
|
24
|
+
def response_with(&block)
|
25
|
+
@response = Apipony::Response.new(&block)
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
##
|
29
|
+
# DSL method to start describind a request
|
30
|
+
def request_with(&block)
|
31
|
+
@request = Apipony::Request.new(&block)
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
##
|
35
|
+
# Create a unique identifier for this endpoint
|
36
|
+
def id
|
37
|
+
File.join(@method.to_s, @url)
|
38
|
+
end
|
43
39
|
|
44
|
-
|
40
|
+
def data
|
41
|
+
OpenStruct.new(
|
42
|
+
description: @description
|
43
|
+
)
|
44
|
+
end
|
45
45
|
|
46
|
-
def
|
47
|
-
|
46
|
+
def ==(other)
|
47
|
+
method == other.method && url == other.url
|
48
48
|
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def build_url(url)
|
53
|
+
File.join(Apipony::Documentation.data.base_url, url)
|
54
|
+
end
|
55
|
+
end
|
49
56
|
end
|
data/lib/apipony/engine.rb
CHANGED
data/lib/apipony/parameter.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
module Apipony
|
2
|
+
class Parameter
|
3
|
+
OPTIONS = %i(name type example required description).freeze
|
4
|
+
|
5
|
+
attr_accessor(*OPTIONS)
|
6
|
+
|
7
|
+
def initialize(name, options = {})
|
8
|
+
@name = name
|
9
|
+
@example = options[:example]
|
10
|
+
@description = options[:description]
|
11
|
+
@type = options.fetch(:type, :string)
|
12
|
+
@required = options.fetch(:required, false)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias required? required
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
OPTIONS.all? do |option|
|
19
|
+
public_send(option) == other.public_send(option)
|
20
|
+
end
|
21
|
+
end
|
10
22
|
end
|
11
23
|
end
|
data/lib/apipony/request.rb
CHANGED
@@ -1,26 +1,33 @@
|
|
1
|
-
##
|
2
1
|
# Model a request that an API user can make.
|
3
2
|
# Includes information about required parameters and required headers
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :params
|
8
|
-
##
|
9
|
-
#:nodoc:
|
10
|
-
attr_accessor :headers
|
3
|
+
module Apipony
|
4
|
+
class Request
|
5
|
+
include Apipony::Shared::Headers
|
11
6
|
|
12
|
-
|
13
|
-
@params = []
|
7
|
+
attr_accessor :params
|
14
8
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
9
|
+
def initialize(&block)
|
10
|
+
@params = []
|
11
|
+
|
12
|
+
instance_eval(&block) if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
# Construct a new parameter
|
16
|
+
def param(name, *params)
|
17
|
+
@params << Apipony::Parameter.new(name, *params)
|
18
|
+
end
|
19
|
+
|
20
|
+
def data
|
21
|
+
OpenStruct.new(
|
22
|
+
headers: @headers,
|
23
|
+
params: params
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def params
|
30
|
+
@params.sort_by { |e| e.required? ? -1 : 0 }
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
data/lib/apipony/response.rb
CHANGED
@@ -1,51 +1,33 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
@status = status
|
5
|
-
@attributes = []
|
6
|
-
@array = array
|
7
|
-
instance_eval(&block) if block_given?
|
8
|
-
end
|
1
|
+
module Apipony
|
2
|
+
class Response
|
3
|
+
include Apipony::Shared::Headers
|
9
4
|
|
10
|
-
|
11
|
-
!! @array
|
12
|
-
end
|
5
|
+
attr_accessor :status, :body
|
13
6
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
find_example
|
7
|
+
def initialize(&block)
|
8
|
+
@status = 200
|
9
|
+
|
10
|
+
instance_eval(&block) if block_given?
|
19
11
|
end
|
20
|
-
end
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
@use_attribute_examples = true
|
13
|
+
def status(code)
|
14
|
+
@status = code if code
|
25
15
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def find_example
|
30
|
-
if @use_attribute_examples
|
31
|
-
build_example_from_attributes
|
16
|
+
|
17
|
+
def body
|
18
|
+
@body = yield if block_given?
|
32
19
|
end
|
33
|
-
@example
|
34
|
-
end
|
35
20
|
|
36
|
-
|
37
|
-
|
38
|
-
@attributes.each do |attr|
|
39
|
-
build[attr.name] = attr.example if attr.example
|
21
|
+
def data?
|
22
|
+
!(@status.nil? && @body.nil?)
|
40
23
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
24
|
+
|
25
|
+
def data
|
26
|
+
OpenStruct.new(
|
27
|
+
status: @status,
|
28
|
+
headers: @headers,
|
29
|
+
body: @body
|
30
|
+
)
|
48
31
|
end
|
49
|
-
@example
|
50
32
|
end
|
51
33
|
end
|
data/lib/apipony/section.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
|
-
##
|
2
1
|
# A section is a way to logically separate your endpoints. All endpoints in
|
3
|
-
# a section should be related in some way.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :title
|
8
|
-
##
|
9
|
-
# :nodoc:
|
10
|
-
# This contains an array of endpoints added with the `endpoint` method of the
|
11
|
-
# DSL
|
12
|
-
attr_accessor :endpoints
|
13
|
-
def initialize(title, &block)
|
14
|
-
@title = title
|
15
|
-
@endpoints = []
|
2
|
+
# a section should be related in some way.
|
3
|
+
module Apipony
|
4
|
+
class Section
|
5
|
+
include Apipony::Shared::Description
|
16
6
|
|
17
|
-
|
18
|
-
|
7
|
+
# What to call this endpoint. This will show up on the generated page.
|
8
|
+
attr_accessor :title
|
9
|
+
|
10
|
+
# This contains an array of endpoints added with the `endpoint`
|
11
|
+
# method of the DSL
|
12
|
+
attr_accessor :endpoints
|
13
|
+
|
14
|
+
def initialize(title, &block)
|
15
|
+
@title = title
|
16
|
+
@endpoints = []
|
17
|
+
|
18
|
+
instance_eval(&block) if block_given?
|
19
|
+
end
|
20
|
+
|
21
|
+
def endpoint(method, url, &block)
|
22
|
+
@endpoints << Apipony::Endpoint.new(method, url, &block)
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
|
25
|
+
def data
|
26
|
+
OpenStruct.new(
|
27
|
+
description: @description
|
28
|
+
)
|
29
|
+
end
|
22
30
|
end
|
23
31
|
end
|
data/lib/apipony/version.rb
CHANGED
data/lib/apipony.rb
CHANGED
@@ -1,31 +1,14 @@
|
|
1
1
|
require 'apipony/engine'
|
2
2
|
|
3
|
-
require 'apipony/
|
3
|
+
require 'apipony/shared/headers'
|
4
|
+
require 'apipony/shared/description'
|
5
|
+
|
4
6
|
require 'apipony/documentation'
|
5
7
|
require 'apipony/section'
|
6
8
|
require 'apipony/endpoint'
|
7
9
|
require 'apipony/response'
|
8
10
|
require 'apipony/request'
|
9
11
|
require 'apipony/parameter'
|
10
|
-
require 'apipony/response_attribute'
|
11
|
-
require 'apipony/example_response'
|
12
12
|
|
13
13
|
module Apipony
|
14
|
-
|
15
|
-
##
|
16
|
-
# This allows you to define a common sub-type of attributes.
|
17
|
-
# A typical example is something like a list of users. If you want to
|
18
|
-
# display all users who created an image, who subscribe to a channel, or who
|
19
|
-
# are in a group, it may be useful if the information on those users is in a
|
20
|
-
# common format. This lets you define one common format, which you can then
|
21
|
-
# merge in to other attributes.
|
22
|
-
# = Example
|
23
|
-
# Apipony.define_attribute_type :user_stub do
|
24
|
-
# attribute :name
|
25
|
-
# attribute :id
|
26
|
-
# end
|
27
|
-
def self.define_attribute_type(name, **params, &block)
|
28
|
-
a = Apipony::ResponseAttribute.new("", **params, &block)
|
29
|
-
Apipony::ResponseAttribute.define_type(name, a)
|
30
|
-
end
|
31
14
|
end
|