grape-batch 1.0.2 → 1.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: 5a517a0d3926d273000e7259b84423dd40a45944
4
- data.tar.gz: 789334e06c793af86de50fd4acc500077e08eef9
3
+ metadata.gz: 629341058e79eb9e77d5f194253924d5e750ad33
4
+ data.tar.gz: a55650fa2bb33ffcbd6687550b8626e1c387fa83
5
5
  SHA512:
6
- metadata.gz: 9995c121e9d6a16727d441437c8c529d9a4e1617d3b7a1ef33f2257f5f632a872e43f751cc2f72c4d621cd31ef966a32e5f37d54905d458c5ab513b4d16371d6
7
- data.tar.gz: 06d85f22c110749398f9058485e7e44c45c260fbccdb542bc8f2022aedfa22c247e54660da6198269edd8b1106f0d2c04a3e968e1f9ce9705e93f48c244adc4e
6
+ metadata.gz: 5c845fcaacb2343e51583e9e076192a5cfcadcaf2fe81aafeb1427beceebadd5bcf31fe3e3c1b0a5a696508fd77976040efc14f82e3beee632f8187096941987
7
+ data.tar.gz: d9332fce70ee22c5994155c1e0dbc2fb1c07873ef90c17772f7598208da4c9895d8a3439eed7b70e58bb7bf534cfcb506a4b31a20678d16d137b70d4d6f5f101
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ script: bundle exec rspec spec
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Rack middleware which extends Grape::API to support request batching.
4
4
 
5
+ ![Build status](https://travis-ci.org/c4mprod/grape-batch.svg?branch=master)
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -26,7 +28,7 @@ This middleware is intended to be used with JSON Grape::API only.
26
28
  ```ruby
27
29
  # grape-batch.rb
28
30
  Rails.application.configure do
29
- config.middleware.insert_before Rack::Sendfile, Grape::Batch::Base
31
+ config.middleware.use Grape::Batch::Base
30
32
  end
31
33
  ```
32
34
 
data/grape-batch.gemspec CHANGED
@@ -6,8 +6,8 @@ require 'grape/batch/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'grape-batch'
8
8
  spec.version = Grape::Batch::VERSION
9
- spec.authors = ['Lionel Oto', 'Cédric Darné']
10
- spec.email = ['lionel.oto@c4mprod.com', 'cedric.darne@c4mprod.com']
9
+ spec.authors = ['Lionel Oto', 'Vincent Falduto', 'Cédric Darné']
10
+ spec.email = ['lionel.oto@c4mprod.com', 'vincent.falduto@c4mprod.com', 'cedric.darne@c4mprod.com']
11
11
  spec.summary = %q{Extends Grape::API to support request batching }
12
12
  spec.homepage = 'https://github.com/c4mprod/grape-batch'
13
13
  spec.license = 'MIT'
data/lib/grape/batch.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'grape/batch/errors'
1
2
  require 'grape/batch/parser'
2
3
  require 'grape/batch/response'
3
4
  require 'grape/batch/version'
@@ -53,7 +54,7 @@ module Grape
53
54
  request_env['REQUEST_METHOD'] = method
54
55
  request_env['PATH_INFO'] = path
55
56
  if method == 'GET'
56
- request_env['rack.input'] = StringIO.new(MultiJson.encode({}))
57
+ request_env['rack.input'] = StringIO.new('{}')
57
58
  request_env['QUERY_STRING'] = URI.encode_www_form(body.to_a)
58
59
  else
59
60
  request_env['rack.input'] = StringIO.new(MultiJson.encode(body))
@@ -0,0 +1,6 @@
1
+ module Grape
2
+ module Batch
3
+ class RequestBodyError < ArgumentError; end
4
+ class TooManyRequestsError < StandardError; end
5
+ end
6
+ end
@@ -1,39 +1,54 @@
1
1
  module Grape
2
2
  module Batch
3
- class RequestBodyError < ArgumentError; end
4
- class TooManyRequestsError < StandardError; end
5
-
6
3
  class Validator
7
- def self.parse(env, limit)
8
- rack_input = env['rack.input'].read
9
- raise RequestBodyError.new('Request body is blank') unless rack_input.length > 0
10
-
11
- begin
12
- batch_body = MultiJson.decode(rack_input)
13
- rescue MultiJson::ParseError
14
- raise RequestBodyError.new('Request body is not valid JSON')
4
+ class << self
5
+ def parse(env, limit)
6
+ batch_body = decode_body(env['rack.input'])
7
+
8
+ requests = batch_body['requests']
9
+ validate_requests(requests, limit)
10
+
11
+ requests.each do |request|
12
+ validate_request(request)
13
+ end
14
+
15
+ requests
15
16
  end
16
17
 
17
- raise RequestBodyError.new('Request body is nil') unless batch_body
18
- raise RequestBodyError.new('Request body is not well formatted') unless batch_body.is_a?(Hash)
18
+ private
19
+
20
+ def decode_body(body)
21
+ raise RequestBodyError.new('Request body is blank') unless body.length > 0
22
+
23
+ begin
24
+ batch_body = MultiJson.decode(body)
25
+ rescue MultiJson::ParseError
26
+ raise RequestBodyError.new('Request body is not valid JSON')
27
+ end
28
+
29
+ raise RequestBodyError.new('Request body is nil') unless batch_body
30
+ raise RequestBodyError.new('Request body is not well formatted') unless batch_body.is_a?(Hash)
19
31
 
20
- batch_requests = batch_body['requests']
21
- raise RequestBodyError.new("'requests' object is missing in request body") unless batch_requests
22
- raise RequestBodyError.new("'requests' is not well formatted") unless batch_requests.is_a?(Array)
23
- raise TooManyRequestsError.new('Batch requests limit exceeded') if batch_requests.count > limit
32
+ batch_body
33
+ end
24
34
 
25
- batch_requests.each do |request|
35
+ def validate_requests(batch_requests, limit)
36
+ raise RequestBodyError.new("'requests' object is missing in request body") unless batch_requests
37
+ raise RequestBodyError.new("'requests' is not well formatted") unless batch_requests.is_a?(Array)
38
+ raise TooManyRequestsError.new('Batch requests limit exceeded') if batch_requests.count > limit
39
+ end
40
+
41
+ def validate_request(request)
26
42
  raise RequestBodyError.new("'method' is missing in one of request objects") unless request['method']
27
43
  raise RequestBodyError.new("'method' is invalid in one of request objects") unless request['method'].is_a?(String)
28
- unless ['GET', 'POST', 'PUT', 'DELETE'].include?(request['method'])
44
+
45
+ unless %w(GET POST PUT DELETE).include?(request['method'])
29
46
  raise RequestBodyError.new("'method' is invalid in one of request objects")
30
47
  end
31
48
 
32
49
  raise RequestBodyError.new("'path' is missing in one of request objects") unless request['path']
33
50
  raise RequestBodyError.new("'path' is invalid in one of request objects") unless request['path'].is_a?(String)
34
51
  end
35
-
36
- batch_requests
37
52
  end
38
53
  end
39
54
  end
@@ -1,14 +1,10 @@
1
- module Grape
2
- module Batch
3
- class Response
4
- def self.format(status, headers, response)
5
- if response
6
- body = response.respond_to?(:body) ? response.body.join : response.join
7
- result = MultiJson.decode(body)
8
- end
9
-
10
- (200..299).include?(status) ? {success: result} : {code: status, error: result['error']}
11
- end
1
+ class Grape::Batch::Response
2
+ def self.format(status, headers, response)
3
+ if response
4
+ body = response.respond_to?(:body) ? response.body.join : response.join
5
+ result = MultiJson.decode(body)
12
6
  end
7
+
8
+ (200..299).include?(status) ? {success: result} : {code: status, error: result['error']}
13
9
  end
14
10
  end
@@ -1,5 +1,5 @@
1
1
  module Grape
2
2
  module Batch
3
- VERSION = '1.0.2'
3
+ VERSION = '1.0.3'
4
4
  end
5
5
  end
@@ -5,8 +5,11 @@ require 'grape'
5
5
  require 'api'
6
6
 
7
7
  RSpec.describe Grape::Batch::Base do
8
- let(:app) { Twitter::API.new }
9
- let(:stack) { Grape::Batch::Base.new(app) }
8
+ before :context do
9
+ @app = Twitter::API.new
10
+ end
11
+
12
+ let(:stack) { Grape::Batch::Base.new(@app) }
10
13
  let(:request) { Rack::MockRequest.new(stack) }
11
14
 
12
15
  def encode(message)
@@ -18,6 +21,7 @@ RSpec.describe Grape::Batch::Base do
18
21
  end
19
22
 
20
23
  describe '/api' do
24
+
21
25
  describe 'GET /hello' do
22
26
  let(:response) { request.get('/api/v1/hello') }
23
27
 
@@ -148,5 +152,13 @@ RSpec.describe Grape::Batch::Base do
148
152
  it { expect(response.body).to eq(encode([{success: 'status 856'}])) }
149
153
  end
150
154
  end
155
+
156
+ describe 'POST' do
157
+ context 'with multiple requests' do
158
+ let(:request_body) { encode({requests: [{method: 'POST', path: '/api/v1/hello'}, {method: 'GET', path: '/api/v1/user/856'}]}) }
159
+ it { expect(response.status).to eq(200) }
160
+ it { expect(decode(response.body).size).to eq(2) }
161
+ end
162
+ end
151
163
  end
152
164
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-batch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lionel Oto
8
+ - Vincent Falduto
8
9
  - Cédric Darné
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2014-11-08 00:00:00.000000000 Z
13
+ date: 2014-11-19 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rack
@@ -112,6 +113,7 @@ dependencies:
112
113
  description:
113
114
  email:
114
115
  - lionel.oto@c4mprod.com
116
+ - vincent.falduto@c4mprod.com
115
117
  - cedric.darne@c4mprod.com
116
118
  executables: []
117
119
  extensions: []
@@ -121,12 +123,14 @@ files:
121
123
  - ".rspec"
122
124
  - ".ruby-gemset"
123
125
  - ".ruby-version"
126
+ - ".travis.yml"
124
127
  - Gemfile
125
128
  - LICENSE.txt
126
129
  - README.md
127
130
  - Rakefile
128
131
  - grape-batch.gemspec
129
132
  - lib/grape/batch.rb
133
+ - lib/grape/batch/errors.rb
130
134
  - lib/grape/batch/parser.rb
131
135
  - lib/grape/batch/response.rb
132
136
  - lib/grape/batch/version.rb