apipony 0.0.9 → 1.0.0.rc1
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.
- 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
|