yodatra 0.1.7 → 0.1.8

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.
@@ -15,7 +15,7 @@ module Yodatra
15
15
 
16
16
  status, headers, response = @block.yield(status, headers, response) unless @block.nil?
17
17
 
18
- headers['Content-Length'] = response.first.length.to_s unless response.nil? || response.first.nil?
18
+ headers['Content-Length'] = response.first.length.to_s unless response.nil? || !response.respond_to?(:first) || response.first.nil?
19
19
 
20
20
  [status, headers, response]
21
21
  end
@@ -6,13 +6,15 @@ module Yodatra
6
6
  end
7
7
 
8
8
  READ_ALL = :read_all
9
- get "/*s" do
9
+ get "/*" do
10
+ pass unless involved?
10
11
  no_route if disabled? READ_ALL
11
12
  model_name.constantize.all.as_json(read_scope).to_json
12
13
  end
13
14
 
14
15
  READ_ONE = :read
15
- get "/*s/:id" do
16
+ get "/*/:id" do
17
+ pass unless involved?
16
18
  no_route if disabled? READ_ONE
17
19
 
18
20
  @one = model_name.constantize.find params[:id]
@@ -20,10 +22,12 @@ module Yodatra
20
22
  end
21
23
 
22
24
  CREATE_ONE = :create
23
- post "/*s" do
25
+ post "/*" do
26
+ pass unless involved?
24
27
  no_route if disabled? CREATE_ONE
25
28
 
26
- @one = model_name.constantize.new self.send("#{model_name.underscore}_params".to_sym)
29
+ hash = self.send("#{model_name.underscore}_params".to_sym)
30
+ @one = model_name.constantize.new hash
27
31
 
28
32
  if @one.save
29
33
  @one.as_json(read_scope).to_json
@@ -34,7 +38,8 @@ module Yodatra
34
38
  end
35
39
 
36
40
  UPDATE_ONE = :update
37
- put "/*s/:id" do
41
+ put "/*/:id" do
42
+ pass unless involved?
38
43
  no_route if disabled? UPDATE_ONE
39
44
 
40
45
  @one = model_name.constantize.find params[:id]
@@ -52,7 +57,8 @@ module Yodatra
52
57
  end
53
58
 
54
59
  DELETE_ONE = :delete
55
- delete "/*s/:id" do
60
+ delete "/*/:id" do
61
+ pass unless involved?
56
62
  no_route if disabled? DELETE_ONE
57
63
 
58
64
  @one = model_name.constantize.find params[:id]
@@ -77,14 +83,20 @@ module Yodatra
77
83
 
78
84
  private
79
85
 
86
+ def involved?
87
+ params[:splat].first == model_name.downcase
88
+ end
89
+
80
90
  # read_scope defaults to all attrs of the model
81
91
  def read_scope
82
92
  {}
83
93
  end
84
94
 
85
95
  # create/update scope defaults to all data given in the POST/PUT
86
- define_method "#{model_name.underscore}_params".to_sym do
87
- params
96
+ def method_missing(name, *args)
97
+ if name.to_s == "#{model_name.underscore}_params"
98
+ return params.reject{|k,v| %w(splat captures).include? k}
99
+ end
88
100
  end
89
101
 
90
102
  def model_name
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'redis'
3
+
4
+ module Yodatra
5
+ class Throttle
6
+ def initialize(app, opts)
7
+ @app = app
8
+ @redis = Redis.new opts[:redis_conf]
9
+ @rpm = opts[:rpm] || 100
10
+ end
11
+
12
+ def call(env)
13
+ req = Rack::Request.new(env)
14
+ key = "throttle:#{req.ip}"
15
+ @redis.incr(key) == 1 && @redis.expire(key, 60)
16
+ if @redis.get(key).to_i > @rpm
17
+ Rack::Response.new('Too many API calls', 403)
18
+ else
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ rescue LoadError
25
+ raise "Error: in order to use Yodatra's throttling middleware you will need Redis. Add 'redis' to your Gemfile or simply gem install 'redis'"
26
+ end
@@ -1,3 +1,3 @@
1
1
  module Yodatra
2
- VERSION = '0.1.7'
2
+ VERSION = '0.1.8'
3
3
  end
@@ -37,7 +37,7 @@ describe 'Model controller' do
37
37
  describe 'Getting a collection of the Model' do
38
38
  context 'default' do
39
39
  it 'should have a GET all route' do
40
- get '/models'
40
+ get '/model'
41
41
 
42
42
  last_response.should be_ok
43
43
  expect(last_response.body).to eq(Model::ALL.map{|e| {:data => e} }.to_json)
@@ -50,7 +50,7 @@ describe 'Model controller' do
50
50
  end
51
51
  end
52
52
  it 'should fail with no route available' do
53
- get '/models'
53
+ get '/model'
54
54
 
55
55
  last_response.should_not be_ok
56
56
  end
@@ -58,7 +58,7 @@ describe 'Model controller' do
58
58
  end
59
59
  describe 'getting an specific Model instance' do
60
60
  it 'should have a GET one route' do
61
- get '/models/2'
61
+ get '/model/2'
62
62
 
63
63
  last_response.should be_ok
64
64
  expect(last_response.body).to eq({ :data => 'c'}.to_json)
@@ -70,7 +70,7 @@ describe 'Model controller' do
70
70
  end
71
71
  end
72
72
  it 'should fail with no route available' do
73
- get '/models/1'
73
+ get '/model/1'
74
74
 
75
75
  last_response.should_not be_ok
76
76
  end
@@ -80,7 +80,7 @@ describe 'Model controller' do
80
80
  context 'with correct model params' do
81
81
  it 'adds creates an instance, saves it and succeed' do
82
82
  expect{
83
- post '/models', {:data => 'd'}
83
+ post '/model', {:data => 'd'}
84
84
  }.to change(Model::ALL, :length).by(1)
85
85
 
86
86
  last_response.should be_ok
@@ -89,7 +89,7 @@ describe 'Model controller' do
89
89
  context 'with incorrect params' do
90
90
  it 'doesn t create an instance and fails' do
91
91
  expect{
92
- post '/models', {}
92
+ post '/model', {}
93
93
  }.to change(Model::ALL, :length).by(0)
94
94
 
95
95
  last_response.should_not be_ok
@@ -103,7 +103,7 @@ describe 'Model controller' do
103
103
  end
104
104
  end
105
105
  it 'should fail with no route available' do
106
- post '/models', {:data => 'd'}
106
+ post '/model', {:data => 'd'}
107
107
 
108
108
  last_response.should_not be_ok
109
109
  end
@@ -113,7 +113,7 @@ describe 'Model controller' do
113
113
  context 'targeting an existing instance' do
114
114
  it 'deletes the instance and succeed' do
115
115
  expect{
116
- delete '/models/1'
116
+ delete '/model/1'
117
117
  }.to change(Model::ALL, :length).by(-1)
118
118
 
119
119
  last_response.should be_ok
@@ -122,7 +122,7 @@ describe 'Model controller' do
122
122
  context 'targeting a not existing instance' do
123
123
  it 'does not delete any instance and fails' do
124
124
  expect{
125
- delete '/models/6'
125
+ delete '/model/6'
126
126
  }.to change(Model::ALL, :length).by(0)
127
127
 
128
128
  last_response.should_not be_ok
@@ -135,7 +135,7 @@ describe 'Model controller' do
135
135
  end
136
136
  end
137
137
  it 'should fail with no route available' do
138
- delete '/models/2'
138
+ delete '/model/2'
139
139
 
140
140
  last_response.should_not be_ok
141
141
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yodatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-20 00:00:00.000000000 Z
12
+ date: 2014-03-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -139,6 +139,7 @@ files:
139
139
  - lib/yodatra/initializers.rb
140
140
  - lib/yodatra/logger.rb
141
141
  - lib/yodatra/models_controller.rb
142
+ - lib/yodatra/throttling.rb
142
143
  - lib/yodatra/utils.rb
143
144
  - lib/yodatra/version.rb
144
145
  - spec/spec_helper.rb