grape-batch 1.0.2 → 1.0.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 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