jko_api 0.1.3
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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +2 -0
- data/app/controllers/api/application_controller.rb +3 -0
- data/jko_api.gemspec +25 -0
- data/lib/jko_api.rb +69 -0
- data/lib/jko_api/class_descendants_builder.rb +46 -0
- data/lib/jko_api/configuration.rb +12 -0
- data/lib/jko_api/constraints.rb +10 -0
- data/lib/jko_api/controller.rb +19 -0
- data/lib/jko_api/controller_helpers.rb +29 -0
- data/lib/jko_api/engine.rb +9 -0
- data/lib/jko_api/middleware.rb +25 -0
- data/lib/jko_api/request_error.rb +33 -0
- data/lib/jko_api/responder.rb +60 -0
- data/lib/jko_api/util.rb +18 -0
- data/lib/jko_api/version.rb +3 -0
- data/lib/jko_api/versioning.rb +27 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3711a73e0bd2f3bb5186bf24f11d4530b9bbeb6c
|
4
|
+
data.tar.gz: e3a28ae1fc62c36cf5a3b77ee0f6820873fb9a75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c6adaaad9e11e56f1971934b7522dae6cc7376e18ddae3b3358202ee73dc85452327d5eab3a62c594e05f525ced2320ff1df5b1acbcf03b8e8ce0faedcbadc6a
|
7
|
+
data.tar.gz: 26a75d36b762ffa83d8f74f93374b5a843f73fdc9d1c80e3f969afdd68722d2055e9d527e239b722f70477304680f2de002490f19c041bace08d668cd4816bc3
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Jeremy Woertink
|
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,99 @@
|
|
1
|
+
# JkoApi
|
2
|
+
|
3
|
+
This is an API versioning gem for rails. Yes, there are a lot of really good and easy ones out there, but the issue with all of them is that when you make a version change, you're copying an entire folder of controllers, specs, and a bunch of routes over just for a single API change.
|
4
|
+
|
5
|
+
This gem lets you make a single change and reversion an API without copying over a billion files and specs.
|
6
|
+
|
7
|
+
## Props
|
8
|
+
|
9
|
+
99% of this gem was written by [Justin Ko](https://github.com/justinko). Since he's lazy and won't make a gem from it, I'm doing it for him :stuck_out_tongue: That's why the gem is named after him.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'jko_api'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install jko_api
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
In your `config/initializers/jko_api.rb` add
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
JkoApi.configure do |c|
|
33
|
+
# This is the default. You can override this if you need a different controller
|
34
|
+
# c.base_controller = Api::ApplicationController
|
35
|
+
# This is the folder name where all the api controllers would go
|
36
|
+
# c.api_namespace = 'api'
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
In your `config/routes.rb`
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
JkoApi.routes self do
|
44
|
+
version 1 do
|
45
|
+
# put base routes and routes for version 1 here
|
46
|
+
resources :foos
|
47
|
+
resources :bars
|
48
|
+
end
|
49
|
+
version 2 # no route changes, maybe just a controller change
|
50
|
+
version 3 do
|
51
|
+
resources :bars, only: [:index] # only changes :bars in version 3
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Place your version 1 controller code in `app/controllers/api/v1`. Controllers should all inherit from `Api::ApplicationController`, or something that inherits from that.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class Api::V1::BarsController < Api::ApplicationController
|
60
|
+
def index
|
61
|
+
# do stuff
|
62
|
+
end
|
63
|
+
def show
|
64
|
+
# show stuff
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
Any controllers that you need to alter will go into a new folder in `app/controllers/api/v2`. Notice in this one we inherit from the last version controller.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
class Api::V2::BarsController < Api::V1::BarsController
|
73
|
+
def index
|
74
|
+
# do different stuff
|
75
|
+
end
|
76
|
+
# no need to redefine show action because it didn't change
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
We can still do this though
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
class Api::V3::BarsController < Api::ApplicationController
|
84
|
+
def index
|
85
|
+
# do different stuff
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
You can test this all by booting up a simple rails app, then do `curl -H "Accept: application/vnd.api.v1+json" http://localhost:3000/bars`
|
91
|
+
|
92
|
+
|
93
|
+
## Contributing
|
94
|
+
|
95
|
+
1. Fork it ( https://github.com/[my-github-username]/jko_api/fork )
|
96
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
97
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
98
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
99
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/jko_api.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jko_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jko_api"
|
8
|
+
spec.version = JkoApi::VERSION
|
9
|
+
spec.authors = ["Jeremy Woertink"]
|
10
|
+
spec.email = ["jeremywoertink@gmail.com"]
|
11
|
+
spec.summary = %q{A Rails API gem}
|
12
|
+
spec.description = %q{Some Rails API code written by JustinKo and ported to a badly written gem}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_dependency "responders", "2.1.0"
|
24
|
+
spec.add_dependency "rails", ">= 4.2.0", "< 5"
|
25
|
+
end
|
data/lib/jko_api.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "active_support/all"
|
2
|
+
require "active_model/railtie"
|
3
|
+
require "action_controller/railtie"
|
4
|
+
require "responders"
|
5
|
+
require "jko_api/version"
|
6
|
+
require "jko_api/class_descendants_builder"
|
7
|
+
require "jko_api/constraints"
|
8
|
+
require "jko_api/controller"
|
9
|
+
require "jko_api/controller_helpers"
|
10
|
+
require "jko_api/middleware"
|
11
|
+
require "jko_api/request_error"
|
12
|
+
require "jko_api/responder"
|
13
|
+
require "jko_api/versioning"
|
14
|
+
require "jko_api/configuration"
|
15
|
+
require "jko_api/util"
|
16
|
+
require "jko_api/engine"
|
17
|
+
|
18
|
+
|
19
|
+
module JkoApi
|
20
|
+
ACCEPT_HEADER_REGEX = /\Aapplication\/vnd\.api(\.v([0-9]))?\+json\z/
|
21
|
+
|
22
|
+
mattr_accessor :configuration, instance_accessor: false
|
23
|
+
mattr_reader :current_version_number, instance_reader: false
|
24
|
+
|
25
|
+
def self.configure
|
26
|
+
self.configuration ||= Configuration.new
|
27
|
+
yield(configuration)
|
28
|
+
setup(configuration.base_controller)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.setup(base_controller)
|
32
|
+
Util.stupid_hack!
|
33
|
+
ClassDescendantsBuilder.build base_controller, level: max_version_number
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.activated?
|
37
|
+
current_version_number.present? && current_version_number > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.reset
|
41
|
+
self.current_version_number = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.current_version_number=(version_number)
|
45
|
+
@@current_version_number = version_number.to_i
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.min_version_number
|
49
|
+
versioning.min_version_number
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.max_version_number
|
53
|
+
versioning.max_version_number
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.versioning
|
57
|
+
@@versioning || raise('call `.versions` first')
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.versions(context, &block)
|
61
|
+
@@versioning = Versioning.new(context, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.routes(context, &block)
|
65
|
+
context.scope(module: JkoApi.configuration.api_namespace, constraints: JkoApi::Constraints, defaults: {format: :json}) do
|
66
|
+
JkoApi.versions(context, &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class ClassDescendantsBuilder
|
3
|
+
LEVEL_REGEX = /\d+/
|
4
|
+
|
5
|
+
def self.build(base_class, level:)
|
6
|
+
base_class.descendants.each do |descendant|
|
7
|
+
new(descendant, level).build
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(descendant, level)
|
12
|
+
@descendant, @level = descendant, level
|
13
|
+
end
|
14
|
+
|
15
|
+
def build
|
16
|
+
initial_level.upto(@level - 1) do |level|
|
17
|
+
build_descendant(level) unless descendant_defined?(level)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def descendant_defined?(level)
|
24
|
+
!!swap_level(level.next).safe_constantize
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_descendant(level)
|
28
|
+
namespace(level.next).constantize.const_set(
|
29
|
+
swap_level(level.next).demodulize,
|
30
|
+
Class.new(swap_level(level).constantize)
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def namespace(level)
|
35
|
+
swap_level(level).deconstantize.presence || 'Object'
|
36
|
+
end
|
37
|
+
|
38
|
+
def swap_level(level)
|
39
|
+
@descendant.name.sub LEVEL_REGEX, level.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def initial_level
|
43
|
+
@descendant.name[LEVEL_REGEX].to_i
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module JkoApi
|
2
|
+
module Constraints
|
3
|
+
def self.matches?(request)
|
4
|
+
request.headers['Accept'] &&
|
5
|
+
request.headers['Accept'].match(ACCEPT_HEADER_REGEX) &&
|
6
|
+
::JkoApi.current_version_number.present?
|
7
|
+
# TODO: add condition config for specific subdomain
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module JkoApi
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include JkoApi::ControllerHelpers
|
7
|
+
skip_authentication # TODO: make this configurable
|
8
|
+
|
9
|
+
self.responder = JkoApi::Responder
|
10
|
+
respond_to :json
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def render_json_errors(status, message = status)
|
16
|
+
render json: JkoApi::RequestError[status, message], status: status
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module JkoApi
|
2
|
+
module ControllerHelpers
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :authenticated
|
7
|
+
self.authenticated = false
|
8
|
+
append_before_action { raise 'setup authentication' unless authenticated }
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def authenticate(*args)
|
13
|
+
options, model_classes = args.extract_options!, args
|
14
|
+
options.reverse_merge! optional: false
|
15
|
+
# This is for use with Devise.
|
16
|
+
# TODO: make this configurable
|
17
|
+
# options[:fallback_to_devise] = !options.delete(:optional)
|
18
|
+
# model_classes.each do |model_class|
|
19
|
+
# acts_as_token_authentication_handler_for model_class, options
|
20
|
+
# end
|
21
|
+
self.authenticated = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def skip_authentication
|
25
|
+
self.authenticated = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
if version_number = extract_version_number(env)
|
9
|
+
::JkoApi.current_version_number = version_number
|
10
|
+
else
|
11
|
+
::JkoApi.reset
|
12
|
+
end
|
13
|
+
@app.call env
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def extract_version_number(env)
|
19
|
+
accept_header = env['HTTP_ACCEPT']
|
20
|
+
return false unless accept_header
|
21
|
+
accept_header[ACCEPT_HEADER_REGEX, 2] ||
|
22
|
+
accept_header[ACCEPT_HEADER_REGEX] && ::JkoApi.max_version_number
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class RequestError
|
3
|
+
def self.[](status, message = status)
|
4
|
+
new(status, message).representer
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :status, :message
|
8
|
+
|
9
|
+
def initialize(status, message)
|
10
|
+
@status, @message = status, message
|
11
|
+
end
|
12
|
+
|
13
|
+
def representer
|
14
|
+
# TODO: integrate this somehow
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def errors
|
20
|
+
Errors.new(MockRequest.new).tap do |errors|
|
21
|
+
errors.add :base, message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class MockRequest
|
26
|
+
include ::ActiveModel::Model
|
27
|
+
|
28
|
+
def representable_type
|
29
|
+
:requests
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class Responder < ActionController::Responder
|
3
|
+
protected
|
4
|
+
|
5
|
+
def display(model, *args)
|
6
|
+
options[:user] ||= controller.current_user
|
7
|
+
options[:wrap] ||= controller.wrap
|
8
|
+
options[:representer] ||= controller.representer
|
9
|
+
|
10
|
+
if first_model = Array.wrap(model).first
|
11
|
+
options[:wrap] ||= first_model.class.table_name
|
12
|
+
end
|
13
|
+
|
14
|
+
options[:wrap] || raise('set the `wrap` in the controller')
|
15
|
+
representer = options[:representer] || first_model.representer
|
16
|
+
|
17
|
+
if Array === model || ActiveRecord::Relation === model
|
18
|
+
representer = representer.for_collection
|
19
|
+
end
|
20
|
+
|
21
|
+
super representer.prepare(model), *args
|
22
|
+
end
|
23
|
+
|
24
|
+
def api_behavior
|
25
|
+
raise MissingRenderer.new(format) unless has_renderer?
|
26
|
+
|
27
|
+
if put?
|
28
|
+
display resource, status: :ok, location: api_location
|
29
|
+
elsif delete?
|
30
|
+
display resource, status: :ok
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def api_location
|
37
|
+
if !options[:location] && controller.controller_name.starts_with?('user_')
|
38
|
+
options[:location] = user_resource_api_location
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_resource_api_location
|
45
|
+
url_helpers = Rails.application.routes.url_helpers
|
46
|
+
url_method = controller.controller_name
|
47
|
+
url_method = url_method.singularize unless resources.many?
|
48
|
+
url_method = url_method + '_url'
|
49
|
+
if resources.many?
|
50
|
+
url_helpers.public_send url_method
|
51
|
+
else
|
52
|
+
url_helpers.public_send url_method, resource
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def json_resource_errors
|
57
|
+
resource.errors
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/jko_api/util.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class Util
|
3
|
+
|
4
|
+
def self.stupid_hack!
|
5
|
+
Rails.application.reload_routes!
|
6
|
+
eager_load_api_controllers
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.eager_load_api_controllers
|
10
|
+
[Rails.root.join('app', 'controllers')].each do |load_path|
|
11
|
+
matcher = /\A#{Regexp.escape(load_path.to_s)}\/(.*)\.rb\Z/
|
12
|
+
Dir.glob("#{load_path}/#{JkoApi.configuration.api_namespace}/**/*.rb").sort.each do |file|
|
13
|
+
require_dependency file.sub(matcher, '\1')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JkoApi
|
2
|
+
class Versioning
|
3
|
+
def initialize(context, &block)
|
4
|
+
@context, @definitions = context, {}
|
5
|
+
instance_eval &block
|
6
|
+
end
|
7
|
+
|
8
|
+
def version(number, &block)
|
9
|
+
@definitions[number] = block || Proc.new {}
|
10
|
+
@context.scope module: "v#{number}", constraints: ->(*) {
|
11
|
+
JkoApi.current_version_number == number
|
12
|
+
} do
|
13
|
+
number.downto(min_version_number) do |i|
|
14
|
+
@context.instance_eval &@definitions[i]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def min_version_number
|
20
|
+
@definitions.keys.min
|
21
|
+
end
|
22
|
+
|
23
|
+
def max_version_number
|
24
|
+
@definitions.keys.max
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jko_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Woertink
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: responders
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.1.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.1.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.0
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '5'
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 4.2.0
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '5'
|
75
|
+
description: Some Rails API code written by JustinKo and ported to a badly written
|
76
|
+
gem
|
77
|
+
email:
|
78
|
+
- jeremywoertink@gmail.com
|
79
|
+
executables: []
|
80
|
+
extensions: []
|
81
|
+
extra_rdoc_files: []
|
82
|
+
files:
|
83
|
+
- ".gitignore"
|
84
|
+
- Gemfile
|
85
|
+
- LICENSE.txt
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- app/controllers/api/application_controller.rb
|
89
|
+
- jko_api.gemspec
|
90
|
+
- lib/jko_api.rb
|
91
|
+
- lib/jko_api/class_descendants_builder.rb
|
92
|
+
- lib/jko_api/configuration.rb
|
93
|
+
- lib/jko_api/constraints.rb
|
94
|
+
- lib/jko_api/controller.rb
|
95
|
+
- lib/jko_api/controller_helpers.rb
|
96
|
+
- lib/jko_api/engine.rb
|
97
|
+
- lib/jko_api/middleware.rb
|
98
|
+
- lib/jko_api/request_error.rb
|
99
|
+
- lib/jko_api/responder.rb
|
100
|
+
- lib/jko_api/util.rb
|
101
|
+
- lib/jko_api/version.rb
|
102
|
+
- lib/jko_api/versioning.rb
|
103
|
+
homepage: ''
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.4.3
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: A Rails API gem
|
127
|
+
test_files: []
|