Skip to content

Commit

Permalink
Allowing use of JSON as the request body for PUT/POST requests, closes
Browse files Browse the repository at this point in the history
  • Loading branch information
andyjeffries committed Mar 21, 2014
1 parent b67622f commit 4b80094
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 9 deletions.
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -382,6 +382,23 @@ class Person < ActiveRestClient::Base
end
```
### Body Types
By default ActiveRestClient puts the body in to normal CGI parameters in K=V&K2=V2 format. However, if you want to use JSON for your PUT/POST requests, you can use either (the other option, the default, is `:form_encoded`):
```ruby
class Person < ActiveRestClient::Base
request_body_type :json
# ...
end
```
or
```ruby
ActiveRestClient::Base.request_body_type = :json
```
### Faking Calls
There are times when an API hasn't been developed yet, so you want to fake the API call response. To do this, you can simply pass a `fake` option when mapping the call containing the response.
Expand Down
32 changes: 26 additions & 6 deletions lib/active_rest_client/configuration.rb
Expand Up @@ -2,6 +2,7 @@ module ActiveRestClient
module Configuration
module ClassMethods
@@base_url = nil
@@request_body_type = :form_encoded
@lazy_load = false

def base_url(value = nil)
Expand All @@ -23,6 +24,23 @@ def base_url=(value)
@@base_url = value
end

def request_body_type(value = nil)
if value.nil?
if @request_body_type.nil?
@@request_body_type
else
@request_body_type
end
else
@request_body_type = value
end
end

def request_body_type=(value)
ActiveRestClient::Logger.info "\033[1;4;32m#{name}\033[0m Request Body Type set to be #{value}"
@@request_body_type = value
end

def adapter=(adapter)
ActiveRestClient::Logger.info "\033[1;4;32m#{name}\033[0m Adapter set to be #{adapter}"
@adapter = adapter
Expand Down Expand Up @@ -70,12 +88,14 @@ def proxy(value = nil)
end

def _reset_configuration!
@base_url = nil
@@base_url = nil
@whiny_missing = nil
@lazy_load = false
@faraday_config = default_faraday_config
@adapter = :patron
@base_url = nil
@@base_url = nil
@request_body_type = nil
@@request_body_type = :form_encoded
@whiny_missing = nil
@lazy_load = false
@faraday_config = default_faraday_config
@adapter = :patron
end

private
Expand Down
14 changes: 13 additions & 1 deletion lib/active_rest_client/request.rb
Expand Up @@ -44,6 +44,14 @@ def base_url
end
end

def request_body_type
if object_is_class?
@object.request_body_type
else
@object.class.request_body_type
end
end

def verbose?
if object_is_class?
@object.verbose
Expand Down Expand Up @@ -171,7 +179,11 @@ def append_get_parameters
end

def prepare_request_body(params = nil)
@body ||= (params || @post_params || {}).map {|k,v| "#{k}=#{CGI.escape(v.to_s)}"}.sort * "&"
if request_body_type == :form_encoded
@body ||= (params || @post_params || {}).map {|k,v| "#{k}=#{CGI.escape(v.to_s)}"}.sort * "&"
elsif request_body_type == :json
@body ||= (params || @post_params || {}).to_json
end
end

def do_request(etag)
Expand Down
2 changes: 1 addition & 1 deletion lib/active_rest_client/version.rb
@@ -1,3 +1,3 @@
module ActiveRestClient
VERSION = "0.9.74"
VERSION = "0.9.75"
end
15 changes: 15 additions & 0 deletions spec/lib/configuration_spec.rb
Expand Up @@ -8,6 +8,7 @@
class ConfigurationExample
include ActiveRestClient::Configuration
base_url "http://www.example.com"
request_body_type :json
end

class ConfigurationExampleBare
Expand Down Expand Up @@ -54,6 +55,20 @@ class ConfigurationExample2
expect(ConfigurationExample2.base_url).to eq("http://specific.example.com")
end

it "should default to a form_encoded request_body_type" do
expect(ActiveRestClient::Base.request_body_type).to eq(:form_encoded)
end

it "should remember the request_body_type" do
expect(ConfigurationExample.request_body_type).to eq(:json)
end

it "should remember the set base_url on a class, overriding a general one" do
ActiveRestClient::Base.request_body_type = :unknown
expect(ActiveRestClient::Base.request_body_type).to eq(:unknown)
expect(ConfigurationExample.request_body_type).to eq(:json)
end

it "should default to non-lazy loading" do
class LazyLoadingConfigurationExample1
include ActiveRestClient::Configuration
Expand Down
16 changes: 16 additions & 0 deletions spec/lib/request_spec.rb
Expand Up @@ -5,6 +5,7 @@
class ExampleOtherClient < ActiveRestClient::Base ; end
class ExampleClient < ActiveRestClient::Base
base_url "http://www.example.com"
request_body_type :form_encoded

before_request do |name, request|
if request.method[:name] == :headers
Expand Down Expand Up @@ -102,6 +103,17 @@ class FilteredBodyExampleClient < ExampleClient
ExampleClient.update id:1234, debug:true
end

it "should encode the body in a form-encoded format by default" do
ActiveRestClient::Connection.any_instance.should_receive(:put).with("/put/1234", "debug=true&test=foo", an_instance_of(Hash)).and_return(OpenStruct.new(body:"{\"result\":true}", headers:{}))
ExampleClient.update id:1234, debug:true, test:'foo'
end

it "should encode the body in a JSON format if specified" do
ActiveRestClient::Connection.any_instance.should_receive(:put).with("/put/1234", %q({"debug":true,"test":"foo"}), an_instance_of(Hash)).and_return(OpenStruct.new(body:"{\"result\":true}", headers:{}))
ExampleClient.request_body_type :json
ExampleClient.update id:1234, debug:true, test:'foo'
end

it "should pass through custom headers" do
ActiveRestClient::Connection.any_instance.should_receive(:get).with("/headers", hash_including("X-My-Header" => "myvalue")).and_return(OpenStruct.new(body:'{"result":true}', headers:{}))
ExampleClient.headers
Expand Down Expand Up @@ -333,6 +345,10 @@ class FilteredBodyExampleClient < ExampleClient
it "should raise an exception if you try to pass in an unsupport method" do
method = {:method => :wiggle, url:"/"}
class RequestFakeObject
def request_body_type
:form_encoded
end

def base_url
"http://www.example.com/"
end
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/result_iterator_spec.rb
Expand Up @@ -98,7 +98,7 @@
item*2
end
end_time = Time.now
expect(end_time-start_time).to be < (4*delay)
expect(end_time-start_time).to be < (6*delay)
expect(response).to eq([6,4,2])
end
end

0 comments on commit 4b80094

Please sign in to comment.