jersey 0.1.0 → 0.2.0

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: 8917e3fd5a219b1f47d717b67c220309e0099e53
4
- data.tar.gz: 877d58392cf2c2ed29f0c716be9ae96e013624d0
3
+ metadata.gz: 7a603102ad901084bf1d4c48b44d4cd7327af468
4
+ data.tar.gz: 4cb8799276e6a144c644fcc7158c114bf1a0eabc
5
5
  SHA512:
6
- metadata.gz: d79189492a2066fc625ad5b89c6fd68874d7c820d65a5def6f506b5de8a9f404cb5e8c1d2cb39db9d83db1c42dfae57668100f2f1883951e150d9c6b3105cc6c
7
- data.tar.gz: b3321888bd62a38ea83d8552be66df3fc28ec1a64179340cfa1eced4f5ad0da42d9af13b7a0a53ba2dfcd9cd1acc9972a1c1add634471404b95de5f2dc8b48ac
6
+ metadata.gz: e74e901b329082e4571ad3624164c57fc620648fa2663e64b74d11bde87200bcfd9ee56df6efcf1238dd0fa1d6be3ce3ecb06f155a27ff44ec0ae27514b63085
7
+ data.tar.gz: 440010607190f4152d45eb196fcfec8f2ca81841c8a3e299ed4eacf688a8370447647c8e0b0a969a0e545d0c0bf358d08ee809ebff11d49aa807c71e25a5063b
data/README.md CHANGED
@@ -149,6 +149,51 @@ class API < Sinatra::Base
149
149
  end
150
150
  ```
151
151
 
152
+ #### `Jersey::Middleware::AutoJson`
153
+
154
+ Uses content type matching regex `/json/` or a request body that
155
+ begins with a `{` to detect and parse json. Exposes json
156
+ via `request.body` and `params` so you can transparently
157
+ accept form-encoded and json bodies.
158
+
159
+ Adds a `#json` method to the `Rack::Request` object.
160
+
161
+ #### Usage
162
+ Use as a Rack middleware
163
+
164
+ ```ruby
165
+ class API < Sinatra::Base
166
+ use Jersey::Middleware::AutoJson
167
+
168
+ post '/test-json' do
169
+ request.json == env['rack.json']
170
+ end
171
+ end
172
+ ```
173
+
174
+ #### `Jersey::Helpers::AutoJsonParams`
175
+ Merges sinatra params Hash with json data parsed by a rack middleware
176
+ that has set `rack.json` on the rack env.
177
+
178
+ If the parsed data is an array, merges by using the array index as a hash key.
179
+
180
+ Json data gets precendence in naming collisions.
181
+
182
+ #### Usage
183
+ Use as a Sinatra Helper
184
+
185
+ Note: works with any Rack middleware that populates `env['rack.json']`
186
+
187
+ ```ruby
188
+ class API < Sinatra::Base
189
+ helpers Jersey::Helpers::AutoJsonParams
190
+
191
+ post "/test-array-params" do
192
+ params[0]
193
+ end
194
+ end
195
+ ```
196
+
152
197
  #### `Jersey::Middleware::RequestID`
153
198
 
154
199
  Creates a random request id for every http request, stored both in thread local storage
@@ -21,6 +21,8 @@ require 'jersey/http_errors'
21
21
  require 'jersey/middleware/request_id'
22
22
  require 'jersey/middleware/error_handler'
23
23
  require 'jersey/middleware/request_logger'
24
+ require 'jersey/middleware/auto_json'
24
25
  require 'jersey/extensions/route_signature'
26
+ require 'jersey/helpers/auto_json_params'
25
27
  require 'jersey/helpers/log'
26
28
  require 'jersey/helpers/success'
@@ -20,10 +20,12 @@ module Jersey::API
20
20
  use Jersey::Middleware::RequestID
21
21
  use Jersey::Middleware::RequestLogger
22
22
  use Jersey::Middleware::ErrorHandler
23
+ use Jersey::Middleware::AutoJson
23
24
 
24
25
  helpers Sinatra::JSON
25
26
  helpers Jersey::Helpers::Log
26
27
  helpers Jersey::Helpers::Success
28
+ helpers Jersey::Helpers::AutoJsonParams
27
29
 
28
30
  set :dump_errors, false
29
31
  set :raise_errors, true
@@ -0,0 +1,29 @@
1
+ module Jersey::Helpers
2
+ module AutoJsonParams
3
+ # Merges sinatra @params Hash with
4
+ # json data parsed by a rack middleware
5
+ # that has set `rack.json` on the rack env.
6
+ #
7
+ # If the parsed data is an array, merges by
8
+ # using the array index as a hash key.
9
+ #
10
+ # Json data gets precendence in naming collisions
11
+ def params
12
+ # we have parsed json!
13
+ if @env['rack.json']
14
+ json = @env['rack.json']
15
+ if json.is_a?(Hash)
16
+ # merge with params
17
+ super.merge(json)
18
+ else
19
+ # covert array to hash by index
20
+ zipped = json.each_with_index
21
+ zipped = zipped.to_a.map(&:reverse)
22
+ super.merge(Hash[zipped])
23
+ end
24
+ else
25
+ super
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # Detects json by customizable regex and
2
+ # by looking for request bodies that being with
3
+ # '{' or '['
4
+ #
5
+ # Sets `rack.json` on rack env, but leaves
6
+ # other vars alone.
7
+ module Jersey::Middleware
8
+ class AutoJson
9
+ JSON_PARSER = lambda { |data| JSON.parse(data) }
10
+ JSON_REGEX = /json/
11
+
12
+ # Configure the :porser and the :json_regex though
13
+ # if you're going to be strict about this you
14
+ # probably shouldn't be using this middleware
15
+ def initialize(app, options = {})
16
+ @app = app
17
+ @parser = options.delete(:parser) || JSON_PARSER
18
+ @json_regex = options.delete(:json_regex) || JSON_REGEX
19
+ end
20
+
21
+ # Make json happen.
22
+ def call(env)
23
+ req = Rack::Request.new(env)
24
+ type = req.media_type
25
+ if type && type.match(@json_regex)
26
+ # raise error if parsing declared json
27
+ begin
28
+ env['rack.json'] = @parser.call(req.body.read)
29
+ rescue => ex
30
+ raise BadRequest, "json parse error in AutoJson: #{ex.message}"
31
+ end
32
+ elsif ["{","["].include?(req.body.read(1))
33
+ # make best effort to parse what looks like json
34
+ req.body.rewind
35
+ env['rack.json'] = @parser.call(req.body.read) rescue nil
36
+ end
37
+ req.body.rewind
38
+ @app.call(env)
39
+ end
40
+ end
41
+ end
42
+
43
+ ## Let's enable folks to use request.json
44
+ ## in their rack apps
45
+ require 'rack/request'
46
+ class Rack::Request
47
+ def json
48
+ env['rack.json']
49
+ end
50
+ end
@@ -1,3 +1,3 @@
1
1
  module Jersey
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,79 @@
1
+ require_relative 'helper'
2
+
3
+ class AutoJsonTest < ApiTest
4
+ class App < Jersey::API::Base
5
+ post '/test-params' do
6
+ "#{params['one']}:#{params['two']}"
7
+ end
8
+
9
+ post '/test-json' do
10
+ "#{request.json['one']}:#{request.json['two']}"
11
+ end
12
+
13
+ post "/test-array" do
14
+ request.json.join(":")
15
+ end
16
+
17
+ post "/test-array-params" do
18
+ params[0]
19
+ end
20
+
21
+ post "/test-auto-parse-fail" do
22
+ request.body.read
23
+ end
24
+ end
25
+
26
+ def test_form_encoded
27
+ post('/test-params', one: "bar")
28
+ assert_equal(200, last_response.status)
29
+ assert_equal("bar:", last_response.body)
30
+ end
31
+
32
+ def test_json
33
+ post('/test-params', {one: "bar"}.to_json)
34
+ assert_equal(200, last_response.status)
35
+ assert_equal("bar:", last_response.body)
36
+ end
37
+
38
+ def test_precedence
39
+ post('/test-params?one=foo', one: "bar")
40
+ assert_equal(200, last_response.status)
41
+ assert_equal("bar:", last_response.body)
42
+ end
43
+
44
+ def test_body_with_json
45
+ post('/test-params?two=foo', {one: "bar"}.to_json)
46
+ assert_equal(200, last_response.status)
47
+ assert_equal("bar:foo", last_response.body)
48
+ end
49
+
50
+ def test_query_string
51
+ post('/test-params?one=bar')
52
+ assert_equal(200, last_response.status)
53
+ assert_equal("bar:", last_response.body)
54
+ end
55
+
56
+ def test_an_array
57
+ post('/test-array', ['foo', 'bar'].to_json)
58
+ assert_equal(200, last_response.status)
59
+ assert_equal("foo:bar", last_response.body)
60
+ end
61
+
62
+ def test_an_array_from_params
63
+ post('/test-array-params', ['foo', 'bar'].to_json)
64
+ assert_equal(200, last_response.status)
65
+ assert_equal("foo", last_response.body)
66
+ end
67
+
68
+ def test_passes_through_auto_parse_fails
69
+ post('/test-auto-parse-fail', "{ HAHA")
70
+ assert_equal(200, last_response.status)
71
+ assert_equal("{ HAHA", last_response.body)
72
+ end
73
+
74
+ def test_query_string_and_body
75
+ post('/test-params?one=bar', {two: "foo"}.to_json)
76
+ assert_equal(200, last_response.status)
77
+ assert_equal("bar:foo", last_response.body)
78
+ end
79
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jersey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - csquared
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-14 00:00:00.000000000 Z
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -114,6 +114,7 @@ files:
114
114
  - lib/jersey/base.rb
115
115
  - lib/jersey/extensions/error_handler.rb
116
116
  - lib/jersey/extensions/route_signature.rb
117
+ - lib/jersey/helpers/auto_json_params.rb
117
118
  - lib/jersey/helpers/log.rb
118
119
  - lib/jersey/helpers/success.rb
119
120
  - lib/jersey/http_errors.rb
@@ -122,12 +123,14 @@ files:
122
123
  - lib/jersey/logging/json_logger.rb
123
124
  - lib/jersey/logging/logfmt_logger.rb
124
125
  - lib/jersey/logging/mixins.rb
126
+ - lib/jersey/middleware/auto_json.rb
125
127
  - lib/jersey/middleware/error_handler.rb
126
128
  - lib/jersey/middleware/request_id.rb
127
129
  - lib/jersey/middleware/request_logger.rb
128
130
  - lib/jersey/setup.rb
129
131
  - lib/jersey/time.rb
130
132
  - lib/jersey/version.rb
133
+ - test/auto_json_test.rb
131
134
  - test/errors_test.rb
132
135
  - test/helper.rb
133
136
  - test/log_test.rb
@@ -154,11 +157,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
157
  version: '0'
155
158
  requirements: []
156
159
  rubyforge_project:
157
- rubygems_version: 2.2.2
160
+ rubygems_version: 2.2.0
158
161
  signing_key:
159
162
  specification_version: 4
160
163
  summary: Write APIs in the New Jersey Style
161
164
  test_files:
165
+ - test/auto_json_test.rb
162
166
  - test/errors_test.rb
163
167
  - test/helper.rb
164
168
  - test/log_test.rb