apic 0.0.2 → 0.0.3

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: 62e91d7da069396fc04033442798fcfa93717c2e
4
- data.tar.gz: 09884be511addc4b3a701d8a16ce9e1373a08358
3
+ metadata.gz: f7f55ccf1ff4c22f1b24ad1969ee107cfa416030
4
+ data.tar.gz: 8080b18679726d48795dced26b908354edb83b41
5
5
  SHA512:
6
- metadata.gz: 34c1269243b0ffe1e7908d577a8776703445a62dfd1cd4aea88a88f2d166e964580c7d4420d2a83296324709b3f8721364fcbb79b2e04f7f62bf97ad538c0a09
7
- data.tar.gz: 4353172bb5077836055d5778326664e3b05a84a6347b4026d3c6f9ed4a65a0fff394e614d997d71bd35cd2ea08b733c8766b332bd72978f49fb09307787a162b
6
+ metadata.gz: 4d66f4291f31f76ebe2b763dabe201a45c0b2d0523f0be8db6d373c9ef2d7cb8200d8dbf3ad53b6756aae9e9852309423a35ce12ca4505f906fbac4925dcf8d2
7
+ data.tar.gz: 2a482d14f24c4aa53db611e89fa10060b981a46d0562d68c07d1511866e7af791ca1ba9d787f29c9588165ae623cf37675cd0d3dda45df6c9206696d2fa9f850
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- = APIc
1
+ # APIc
2
2
 
3
3
  ## What is it?
4
4
 
@@ -46,7 +46,7 @@ To make this as simple and painless as possible, APIc exposes a DSL to your cont
46
46
  APIc knows what type of routes are available and will automatically add in the _method parameter and value for PATCH and DELETE requests.
47
47
 
48
48
  ```
49
- class TestController << ActionController.base
49
+ class TestController < ActionController.base
50
50
 
51
51
  apic_action_params create: [:name, :acceptance]
52
52
 
@@ -59,7 +59,7 @@ end
59
59
 
60
60
  ### Initializer
61
61
 
62
- The apic:install generator will add in a default intializer providing examples of the route matching and authentication filtering.
62
+ The apic:install generator will mount APIc to /apic and add in a default intializer providing examples of the route matching and authentication filtering.
63
63
 
64
64
  ```
65
65
  config/initializers/apic.rb
@@ -76,6 +76,21 @@ For example, if you have namespecs all of your api endpoints to /api/v1/ simply
76
76
  Apic.route_matcher = /\/api\/v1\//
77
77
  ```
78
78
 
79
+ #### Custom Headers
80
+
81
+ When you add headers in APIc we automatically create typeahead options for standard request headers.
82
+ However, many, many people define their own headers for use in a custom API. APIc lets you specify
83
+ any custom headers you want to make available to the typeahead by setting an array of header names
84
+ in the apic.rb initializer.
85
+
86
+ ```
87
+ Apic.custom_headers = %w(HTTP-MY-AWESOME-HEADER HTTP-ANTOHER-AWESOME-HEADER)
88
+ ```
89
+
90
+ Of course you can create any header you want in the UI, even if it is not defined as a custom header,
91
+ but for other people using this tool in your organization or even in public would probably appreciate it if
92
+ they didn't have to remember exactly what that header field name was!.
93
+
79
94
  #### Authentication filters
80
95
 
81
96
  When testing your API it is often convenient to know which routes require authentication as you will need to add those headers before sending your request.
@@ -85,4 +100,40 @@ If you specify in your configuration the before_filter you are using for authent
85
100
  Apic.authentication_filter = :authenticate
86
101
  ```
87
102
 
103
+ ## Requirements
104
+
105
+ APIc _should_ work on any Rails 3.2+ application out of the box.
106
+ If it doesn't, send me a pull request!!
107
+
108
+ ## Roadmap
109
+
110
+ APIc is still in the very early days. I've gone with greater developer (as in me!) productivity at the cost of more dependencies
111
+ in the gem. Moving forward, I'd like to see the following:
112
+
113
+ - Rebuild views with vanilla erb so I can drop slim-rails
114
+ - Find someone who rocks at css/design and ditch bootstrap/sass
115
+ - Rewrite the jquery plugins in vanilla js so I can drop jquery and coffee
116
+
117
+ Under the 'fun' section comes
118
+
119
+ - Implement OAuth and Basic authentication as well as token caching
120
+ - Collect and display response time metrics
121
+ - Spec and Doc the crap out of it!
122
+
123
+ I guess when all that is done, APIc goes to 1.0.0
124
+
125
+ # Contribute
126
+
127
+ Just Do It!
128
+
88
129
  This project rocks and uses MIT-LICENSE.
130
+
131
+
132
+ ### Change log
133
+
134
+ #### 2013.10.05
135
+ - Removed the default 'api' route matching.
136
+ - Rationalized route matching to ensure that internal and apic routes are not exposed as endpoints.
137
+ - Altered history links to replay on single click instead of double click.
138
+ - added support for customized headers typeahead matching when setting a header.
139
+
@@ -13,3 +13,4 @@
13
13
  //= require_tree .
14
14
  //
15
15
  //= require bootstrap-modal
16
+ //= require bootstrap-typeahead
@@ -13,7 +13,7 @@ $.fn.extend
13
13
 
14
14
  $.each endpoints, (key, value) ->
15
15
  option = $('<option>'+ key + '</option>')
16
- option.text('[restricted] ' + option.text()) if value.authorization_required
16
+ option.text('[restricted] ' + option.text()) if value.authentication_required
17
17
  $(settings.select).append(option)
18
18
 
19
19
  change = ->
@@ -1,21 +1,56 @@
1
1
  $.fn.extend
2
2
  httpHeaders: (options) ->
3
- settings =
4
- presets: {'Content-Type': 'application/json'}
3
+ defaults =
4
+ presets: {'Content-Type': 'application/json'},
5
+ headers: [
6
+ 'Accept',
7
+ 'Accept-Charset',
8
+ 'Accept-Datetime',
9
+ 'Accept-Encoding',
10
+ 'Accept-Language',
11
+ 'Authorization',
12
+ 'Cache-Control',
13
+ 'Connection',
14
+ 'Content-Length',
15
+ 'Content-MD5',
16
+ 'Content-Type',
17
+ 'Cookie',
18
+ 'Date',
19
+ 'Expect',
20
+ 'From',
21
+ 'Host',
22
+ 'If-Match',
23
+ 'If-Modified-Since',
24
+ 'If-None-Match',
25
+ 'If-Range',
26
+ 'If-Unmodified-Since',
27
+ 'Max-Forwards',
28
+ 'Origin',
29
+ 'Pragma',
30
+ 'Proxy-Authorization',
31
+ 'Range',
32
+ 'Referer',
33
+ 'TE',
34
+ 'Upgrade',
35
+ 'User-Agent',
36
+ 'Via',
37
+ 'Warning'
38
+ ]
5
39
 
6
40
  $.each $(this).data(), (key, value) ->
7
- settings[key] = value
41
+ defaults[key] = $.extend defaults[key], value
8
42
 
9
- settings = $.extend settings, options
43
+ settings = $.extend defaults, options
10
44
 
11
45
  $(this).data('items', settings.presets)
12
46
 
13
47
  self = this
14
48
 
49
+ $('#inputHttpHeaderFieldName').typeahead({source: settings.headers})
15
50
  selected = undefined
16
51
 
17
52
  add = ->
18
- name = $('#selectHttpHeaderFieldName').val()
53
+ name = $('#inputHttpHeaderFieldName').val()
19
54
  value = $('#inputHttpHeaderValue').val()
20
55
  if !!name and !!value
21
56
  tmp_items = items()
@@ -37,12 +72,12 @@ $.fn.extend
37
72
  name = self.selected.data('key')
38
73
  headers = items()
39
74
  value = headers[name]
40
- $('#selectHttpHeaderFieldName').val(name)
75
+ $('inputHttpHeaderFieldName').val(name)
41
76
  $('#inputHttpHeaderValue').val(value)
42
77
  $('#httpHeadersModal').modal('show')
43
78
 
44
79
  create = ->
45
- $('#selectHttpHeaderFieldName').prop("selectedIndex",0)
80
+ $('#inputHttpHeaderFieldName').val('')
46
81
  $('#inputHttpHeaderValue').val('')
47
82
  $('#httpHeadersModal').modal('show')
48
83
 
@@ -41,8 +41,9 @@ $.fn.extend
41
41
  else
42
42
  li.removeClass('active')
43
43
 
44
- #$(self).on('refresh', -> refresh.apply self)
44
+ $(self).on('refresh', -> refresh.apply self)
45
45
  $(self).on('add', (e, item) -> add.apply self, [item])
46
- $('.xhr-history').on('dblclick', 'li', (e) -> replay this)
46
+ $('.xhr-history').on('click', 'li', (e) -> replay this)
47
47
  $('.toggle-history').on('click', -> show.apply self)
48
+
48
49
  this
@@ -1,8 +1,13 @@
1
1
  module Apic
2
2
  class ApplicationController < ActionController::Base
3
+
4
+ before_filter :custom_headers, :endpoints
5
+
3
6
  def index
4
- Rails.logger.debug endpoints
5
- endpoints
7
+ end
8
+
9
+ def custom_headers
10
+ @custom_headers ||= Apic::custom_headers
6
11
  end
7
12
 
8
13
  def endpoints
@@ -1,7 +1,7 @@
1
1
  div.row.headers
2
2
  div.http-headers-component
3
3
  h4 HTTP Headers
4
- div.http-headers
4
+ div.http-headers(data-headers="#{@custom_headers}")
5
5
  ul.http-headers-list.nav.nav-list
6
6
 
7
7
  div.http-headers-controls
@@ -18,45 +18,13 @@ div.row.headers
18
18
  div.modal-body
19
19
  form.form-horizontal
20
20
  div.control-group
21
- label.control-label(for='selectHttpHeaderFieldName') Header
21
+ label.control-label(for='inputHttpHeaderFieldName') Header
22
22
  div.controls
23
- select(id='selectHttpHeaderFieldName')
24
- option Accept
25
- option Accept-Charset
26
- option Accept-Datetime
27
- option Accept-Encoding
28
- option Accept-Language
29
- option Authorization
30
- option Cache-Control
31
- option Connection
32
- option Content-Length
33
- option Content-MD5
34
- option Content-Type
35
- option Cookie
36
- option Date
37
- option Expect
38
- option From
39
- option Host
40
- option If-Match
41
- option If-Modified-Since
42
- option If-None-Match
43
- option If-Range
44
- option If-Unmodified-Since
45
- option Max-Forwards
46
- option Origin
47
- option Pragma
48
- option Proxy-Authorization
49
- option Range
50
- option Referer
51
- option TE
52
- option Upgrade
53
- option User-Agent
54
- option Via
55
- option Warning
23
+ input#inputHttpHeaderFieldName
56
24
  div.control-group
57
25
  label.control-label(for='inputHttpHeaderValue') Value
58
26
  div.controls
59
- input.input-xxlarge(type='text' id='inputHttpHeaderValue' placeholder='value')
27
+ input.input-xxlarge#inputHttpHeaderValue(type='text' placeholder='value')
60
28
 
61
29
  div.modal-footer
62
30
  a.btn(href='#' data-dismiss='modal') Cancel
data/lib/apic.rb CHANGED
@@ -2,52 +2,39 @@ require 'apic/params_cache'
2
2
  require "apic/extension"
3
3
  require "apic/engine"
4
4
  require "apic/generators/install_generator"
5
+ require 'apic/route_wrapper'
5
6
  module Apic
6
7
 
7
8
  mattr_accessor :authentication_filter
8
9
  @@authentication_filter = nil
9
10
 
10
11
  mattr_accessor :route_matcher
11
- @@route_matcher = /\/api\//
12
+ @@route_matcher = /.*/
12
13
 
14
+ mattr_accessor :custom_headers
15
+ @@custom_headers = []
13
16
 
17
+ class << self
14
18
 
15
- def self.endpoints
16
- @endpoints ||= Rails.application.routes.routes.reduce({}) do |hash, route|
17
- if route.path.spec.to_s =~ @@route_matcher
18
- route_spec = {
19
- path: route.path.spec.to_s.gsub("(.:format)",".json"),
20
- parts: route.parts - [:format],
21
- verb: route.verb.source.gsub(/[\^\$]/,''),
22
- template: template_for(route.defaults[:controller], route.defaults[:action])
23
- }
24
- if %(PATCH DELETE).include? route_spec[:verb]
25
- route_spec[:template] = route_spec[:template] + ['_method']
26
- end
27
- if requires_authorization route.defaults[:controller], route.defaults[:action]
28
- route_spec[:authorization_required] = true
29
- end
30
-
31
- hash[[route_spec[:verb],route_spec[:path]].join(' ')] = route_spec
32
- end
33
- hash
19
+ def endpoints
20
+ @endpoints ||= endpoints_hash
34
21
  end
35
- end
36
22
 
37
- def self.requires_authorization(controller, action_name)
38
- return false unless @@authentication_filter
39
- controller = (controller + '_controller').camelize.constantize
40
- controller._process_action_callbacks.any? do |callback|
41
- eval <<-RUBY_EVAL
42
- #{callback.filter == @@authentication_filter} && #{callback.instance_values['compiled_options']}
43
- RUBY_EVAL
23
+ private
24
+
25
+ def endpoints_hash
26
+ Hash.new do |hash, route|
27
+ wrapper = RouteWrapper.new(route)
28
+ hash[wrapper.endpoint] = wrapper.to_h unless wrapper.internal?
29
+ end.tap do |hash|
30
+ Rails.application.routes.routes.each do |route|
31
+ if route.path.spec.to_s =~ @@route_matcher
32
+ hash[route]
33
+ end
34
+ end
35
+ end
44
36
  end
45
37
  end
46
-
47
- def self.template_for(controller, action)
48
- (controller + '_controller').camelize.constantize
49
- Apic::ParamsCache.params_for(controller, action) || []
50
- end
51
38
  end
52
39
 
53
40
 
@@ -1,10 +1,18 @@
1
1
  # Specify a route matcher to restrict which application routes are available
2
2
  # in the console. By default all routes will be loaded
3
3
  #
4
- # Apic.route_matcher = /\/api\/v1\//
4
+ # Apic.route_matcher = /.*/
5
5
  #
6
6
  #
7
- # Specify your authentication filter. Requests that use this filter will be marked
7
+ # Specify your authentication filter.
8
+ # Requests that use this filter will be marked
8
9
  # as restricted in the Api endpoints list.
9
10
  #
10
11
  # Apic.authentication_filter = :authenticate
12
+ #
13
+ #
14
+ # Declare custom headers.
15
+ # These headers are added to the list of matches in the UI's typeahead
16
+ # used to set headers for requests.
17
+ #
18
+ # Apic.custom_headers = %w(Total-Awesomeness Http-More-Awesome-Than-Awesome)
@@ -0,0 +1,70 @@
1
+ require 'delegate'
2
+
3
+ module Apic
4
+ class RouteWrapper < SimpleDelegator
5
+
6
+ def to_h
7
+ endpoint = {
8
+ path: path,
9
+ parts: parts - [:format],
10
+ verb: verb,
11
+ template: template,
12
+ key: key,
13
+ authentication_required: authentication_required
14
+ }
15
+
16
+ if %(PATCH DELETE).include? verb
17
+ endpoint[:template] << '_method'
18
+ end
19
+
20
+ endpoint
21
+ end
22
+
23
+ def endpoint
24
+ [verb, path].join(' ')
25
+ end
26
+
27
+ def internal?
28
+ requirements[:controller].to_s =~ %r{\Arails/(info|welcome)} ||
29
+ path =~ %r{\A#{Rails.application.config.assets.prefix}} ||
30
+ path =~ %r{\A\/apic}
31
+ end
32
+
33
+ private
34
+
35
+ def authentication_required
36
+ return false unless Apic.authentication_filter
37
+ controller._process_action_callbacks.any? do |callback|
38
+ eval <<-RUBY_EVAL
39
+ #{callback.filter == Apic.authentication_filter} && #{callback.instance_values['compiled_options']}
40
+ RUBY_EVAL
41
+ end
42
+ end
43
+
44
+ def controller
45
+ if controller = requirements[:controller]
46
+ [controller.to_s, 'controller'].join('_').camelize.constantize
47
+ end
48
+ end
49
+
50
+ def verb
51
+ super.source.gsub(/[$^]/, '')
52
+ end
53
+
54
+ def path
55
+ super.spec.to_s.gsub("(.:format)",".json")
56
+ end
57
+
58
+ def action_name
59
+ requirements[:action]
60
+ end
61
+
62
+ def key
63
+ [verb, path].join(' ')
64
+ end
65
+
66
+ def template
67
+ Apic::ParamsCache.params_for(controller, action_name) || []
68
+ end
69
+ end
70
+ end
data/lib/apic/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Apic
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Randy Morgan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-02 00:00:00.000000000 Z
11
+ date: 2013-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -94,8 +94,9 @@ dependencies:
94
94
  - - '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: Apic is a mountable rails engine that enables a web based console for
98
- testing api endpoints.
97
+ description: APIc is a bolt on API console for Rails 3+ applications. It rounds up
98
+ your endpoints and makes it dead easy to configure, send, review and replay any
99
+ request.
99
100
  email:
100
101
  - digital.ipseity@gmail.com
101
102
  executables: []
@@ -128,6 +129,7 @@ files:
128
129
  - lib/apic/generators/install_generator.rb
129
130
  - lib/apic/generators/templates/apic.rb
130
131
  - lib/apic/params_cache.rb
132
+ - lib/apic/route_wrapper.rb
131
133
  - lib/apic/version.rb
132
134
  - lib/apic.rb
133
135
  - lib/tasks/apic_tasks.rake