batch_api 0.0.8 → 0.1.0
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.
- data/changelog.md +4 -0
- data/lib/batch_api.rb +12 -0
- data/lib/batch_api/errors/base.rb +2 -2
- data/lib/batch_api/operation.rb +2 -74
- data/lib/batch_api/operation/rack.rb +74 -0
- data/lib/batch_api/operation/rails.rb +42 -0
- data/lib/batch_api/processor.rb +8 -1
- data/lib/batch_api/version.rb +1 -1
- metadata +6 -4
data/changelog.md
CHANGED
data/lib/batch_api.rb
CHANGED
@@ -5,7 +5,19 @@ require 'batch_api/processor'
|
|
5
5
|
require 'batch_api/middleware'
|
6
6
|
|
7
7
|
module BatchApi
|
8
|
+
|
9
|
+
# Public: access the main Batch API configuration object.
|
10
|
+
#
|
11
|
+
# Returns a BatchApi::Configuration instance
|
8
12
|
def self.config
|
9
13
|
@config ||= Configuration.new
|
10
14
|
end
|
15
|
+
|
16
|
+
# Public: are we in Rails? This partly exists just so that you
|
17
|
+
# can stub it in the tests.
|
18
|
+
#
|
19
|
+
# Returns true if Rails is a defined constant, false otherwise.
|
20
|
+
def rails?
|
21
|
+
defined?(Rails)
|
22
|
+
end
|
11
23
|
end
|
@@ -12,7 +12,7 @@ module BatchApi
|
|
12
12
|
# Public: the error details as a hash, which can be returned
|
13
13
|
# to clients as JSON.
|
14
14
|
def body
|
15
|
-
message = if expose_backtrace?
|
15
|
+
message = if self.class.expose_backtrace?
|
16
16
|
{
|
17
17
|
message: @error.message,
|
18
18
|
backtrace: @error.backtrace
|
@@ -37,7 +37,7 @@ module BatchApi
|
|
37
37
|
|
38
38
|
# Internal: whether the backtrace should be exposed in the response.
|
39
39
|
# Currently Rails-specific, needs to be generalized (to ENV["RACK_ENV"])?
|
40
|
-
def expose_backtrace?
|
40
|
+
def self.expose_backtrace?
|
41
41
|
!Rails.env.production?
|
42
42
|
end
|
43
43
|
end
|
data/lib/batch_api/operation.rb
CHANGED
@@ -1,74 +1,2 @@
|
|
1
|
-
require 'batch_api/
|
2
|
-
|
3
|
-
module BatchApi
|
4
|
-
# Public: an individual batch operation.
|
5
|
-
class Operation
|
6
|
-
class MalformedOperationError < ArgumentError; end
|
7
|
-
|
8
|
-
attr_accessor :method, :url, :params, :headers
|
9
|
-
attr_accessor :env, :app, :result
|
10
|
-
|
11
|
-
# Public: create a new Batch Operation given the specifications for a batch
|
12
|
-
# operation (as defined above) and the request environment for the main
|
13
|
-
# batch request.
|
14
|
-
def initialize(op, base_env, app)
|
15
|
-
@op = op
|
16
|
-
|
17
|
-
@method = op["method"]
|
18
|
-
@url = op["url"]
|
19
|
-
@params = op["params"] || {}
|
20
|
-
@headers = op["headers"] || {}
|
21
|
-
|
22
|
-
raise MalformedOperationError,
|
23
|
-
"BatchAPI operation must include method (received #{@method.inspect}) " +
|
24
|
-
"and url (received #{@url.inspect})" unless @method && @url
|
25
|
-
|
26
|
-
@app = app
|
27
|
-
# deep_dup to avoid unwanted changes across requests
|
28
|
-
@env = BatchApi::Utils.deep_dup(base_env)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Execute a batch request, returning a BatchResponse object. If an error
|
32
|
-
# occurs, it returns the same results as Rails would.
|
33
|
-
def execute
|
34
|
-
process_env
|
35
|
-
begin
|
36
|
-
response = @app.call(@env)
|
37
|
-
rescue => err
|
38
|
-
response = BatchApi::Errors::Operation.new(err).render
|
39
|
-
end
|
40
|
-
BatchApi::Response.new(response)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Internal: customize the request environment. This is currently done
|
44
|
-
# manually and feels clunky and brittle, but is mostly likely fine, though
|
45
|
-
# there are one or two environment parameters not yet adjusted.
|
46
|
-
def process_env
|
47
|
-
path, qs = @url.split("?")
|
48
|
-
|
49
|
-
# Headers
|
50
|
-
headrs = (@headers || {}).inject({}) do |heads, (k, v)|
|
51
|
-
heads.tap {|h| h["HTTP_" + k.gsub(/\-/, "_").upcase] = v}
|
52
|
-
end
|
53
|
-
# preserve original headers unless explicitly overridden
|
54
|
-
@env.merge!(headrs)
|
55
|
-
|
56
|
-
# method
|
57
|
-
@env["REQUEST_METHOD"] = @method.upcase
|
58
|
-
|
59
|
-
# path and query string
|
60
|
-
@env["REQUEST_URI"] = @env["REQUEST_URI"].gsub(/\/batch.*/, @url)
|
61
|
-
@env["REQUEST_PATH"] = path
|
62
|
-
@env["ORIGINAL_FULLPATH"] = @env["PATH_INFO"] = @url
|
63
|
-
|
64
|
-
@env["rack.request.query_string"] = qs
|
65
|
-
@env["QUERY_STRING"] = qs
|
66
|
-
|
67
|
-
# parameters
|
68
|
-
@env["rack.request.form_hash"] = @params
|
69
|
-
@env["action_dispatch.request.parameters"] = @params
|
70
|
-
@env["action_dispatch.request.request_parameters"] = @params
|
71
|
-
@env["rack.request.query_hash"] = @method == "get" ? @params : nil
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
1
|
+
require 'batch_api/operation/rack'
|
2
|
+
require 'batch_api/operation/rails' if defined?(Rails)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'batch_api/response'
|
2
|
+
|
3
|
+
module BatchApi
|
4
|
+
# Public: an individual batch operation.
|
5
|
+
module Operation
|
6
|
+
class MalformedOperationError < ArgumentError; end
|
7
|
+
|
8
|
+
class Rack
|
9
|
+
attr_accessor :method, :url, :params, :headers
|
10
|
+
attr_accessor :env, :app, :result
|
11
|
+
|
12
|
+
# Public: create a new Batch Operation given the specifications for a batch
|
13
|
+
# operation (as defined above) and the request environment for the main
|
14
|
+
# batch request.
|
15
|
+
def initialize(op, base_env, app)
|
16
|
+
@op = op
|
17
|
+
|
18
|
+
@method = op["method"]
|
19
|
+
@url = op["url"]
|
20
|
+
@params = op["params"] || {}
|
21
|
+
@headers = op["headers"] || {}
|
22
|
+
|
23
|
+
raise MalformedOperationError,
|
24
|
+
"BatchAPI operation must include method (received #{@method.inspect}) " +
|
25
|
+
"and url (received #{@url.inspect})" unless @method && @url
|
26
|
+
|
27
|
+
@app = app
|
28
|
+
# deep_dup to avoid unwanted changes across requests
|
29
|
+
@env = BatchApi::Utils.deep_dup(base_env)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Execute a batch request, returning a BatchResponse object. If an error
|
33
|
+
# occurs, it returns the same results as Rails would.
|
34
|
+
def execute
|
35
|
+
process_env
|
36
|
+
begin
|
37
|
+
response = @app.call(@env)
|
38
|
+
rescue => err
|
39
|
+
response = BatchApi::Errors::Operation.new(err).render
|
40
|
+
end
|
41
|
+
BatchApi::Response.new(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Internal: customize the request environment. This is currently done
|
45
|
+
# manually and feels clunky and brittle, but is mostly likely fine, though
|
46
|
+
# there are one or two environment parameters not yet adjusted.
|
47
|
+
def process_env
|
48
|
+
path, qs = @url.split("?")
|
49
|
+
|
50
|
+
# Headers
|
51
|
+
headrs = (@headers || {}).inject({}) do |heads, (k, v)|
|
52
|
+
heads.tap {|h| h["HTTP_" + k.gsub(/\-/, "_").upcase] = v}
|
53
|
+
end
|
54
|
+
# preserve original headers unless explicitly overridden
|
55
|
+
@env.merge!(headrs)
|
56
|
+
|
57
|
+
# method
|
58
|
+
@env["REQUEST_METHOD"] = @method.upcase
|
59
|
+
|
60
|
+
# path and query string
|
61
|
+
@env["REQUEST_URI"] = @env["REQUEST_URI"].gsub(/\/batch.*/, @url)
|
62
|
+
@env["REQUEST_PATH"] = path
|
63
|
+
@env["ORIGINAL_FULLPATH"] = @env["PATH_INFO"] = @url
|
64
|
+
|
65
|
+
@env["rack.request.query_string"] = qs
|
66
|
+
@env["QUERY_STRING"] = qs
|
67
|
+
|
68
|
+
# parameters
|
69
|
+
@env["rack.request.form_hash"] = @params
|
70
|
+
@env["rack.request.query_hash"] = @method == "get" ? @params : nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'batch_api/operation/rack'
|
2
|
+
|
3
|
+
module BatchApi
|
4
|
+
# Public: an individual batch operation.
|
5
|
+
module Operation
|
6
|
+
class Rails < Operation::Rack
|
7
|
+
# Public: create a new Rails Operation. It does all that Rack does
|
8
|
+
# and also some additional Rails-specific processing.
|
9
|
+
def initialize(op, base_env, app)
|
10
|
+
super
|
11
|
+
@params = params_with_path_components
|
12
|
+
end
|
13
|
+
|
14
|
+
# Internal: customize the request environment. This is currently done
|
15
|
+
# manually and feels clunky and brittle, but is mostly likely fine, though
|
16
|
+
# there are one or two environment parameters not yet adjusted.
|
17
|
+
def process_env
|
18
|
+
# parameters
|
19
|
+
super
|
20
|
+
@env["action_dispatch.request.parameters"] = @params
|
21
|
+
@env["action_dispatch.request.request_parameters"] = @params
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Internal: process the params the Rails way, merging in the
|
27
|
+
# path_parameters. If the route can't be recognized, it will
|
28
|
+
# leave the params unchanged.
|
29
|
+
#
|
30
|
+
# Returns the updated params.
|
31
|
+
def params_with_path_components
|
32
|
+
begin
|
33
|
+
path_params = ::Rails.application.routes.recognize_path(@url, @op)
|
34
|
+
@params.merge(path_params)
|
35
|
+
rescue
|
36
|
+
@params
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/lib/batch_api/processor.rb
CHANGED
@@ -82,11 +82,18 @@ module BatchApi
|
|
82
82
|
"#{ops.length} were provided"
|
83
83
|
else
|
84
84
|
ops.map do |op|
|
85
|
-
|
85
|
+
self.class.operation_klass.new(op, @env, @app)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
# Internal: which operation class to used.
|
91
|
+
#
|
92
|
+
# Returns Batch::Operation::(Rack|Rails) depending on the environment
|
93
|
+
def self.operation_klass
|
94
|
+
BatchApi.rails? ? Operation::Rails : Operation::Rack
|
95
|
+
end
|
96
|
+
|
90
97
|
# Internal: Processes any other provided options for validity.
|
91
98
|
# Currently, the :sequential option is REQUIRED (until parallel
|
92
99
|
# implementation is created).
|
data/lib/batch_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: batch_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
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: 2012-08-
|
12
|
+
date: 2012-08-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -121,6 +121,8 @@ files:
|
|
121
121
|
- lib/batch_api/errors/operation.rb
|
122
122
|
- lib/batch_api/errors/request.rb
|
123
123
|
- lib/batch_api/middleware.rb
|
124
|
+
- lib/batch_api/operation/rack.rb
|
125
|
+
- lib/batch_api/operation/rails.rb
|
124
126
|
- lib/batch_api/operation.rb
|
125
127
|
- lib/batch_api/processor/strategies/sequential.rb
|
126
128
|
- lib/batch_api/processor.rb
|
@@ -147,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
149
|
version: '0'
|
148
150
|
segments:
|
149
151
|
- 0
|
150
|
-
hash:
|
152
|
+
hash: 4154907758036208164
|
151
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
154
|
none: false
|
153
155
|
requirements:
|
@@ -156,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
158
|
version: '0'
|
157
159
|
segments:
|
158
160
|
- 0
|
159
|
-
hash:
|
161
|
+
hash: 4154907758036208164
|
160
162
|
requirements: []
|
161
163
|
rubyforge_project:
|
162
164
|
rubygems_version: 1.8.21
|