yodatra 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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