xsr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ee83ab8ac671bbbc63a6e1dd9fe9e1094617265
4
+ data.tar.gz: e33c6b188b742d4ceb395e3b14beba659579c3fb
5
+ SHA512:
6
+ metadata.gz: 240808f43cef65593b98b4ada88f7970201929586c9485e2ea5d60a45dc06700413117f689295923d610f7cf99f3389a67a0c3433e6d2b8a5407a1f1e72701d9
7
+ data.tar.gz: a2398e4e935dad8f11c70f3203797ba292392312f084300e02351ce94c130fcfd944d8b7df8c7d2584feb5280a9cbd473cd1719e0960745104de5b586e07f8fc
data/.gitignore ADDED
@@ -0,0 +1,36 @@
1
+ .gitignore
2
+ *.gem
3
+ *.gs
4
+ *.rbc
5
+ /.config
6
+ /coverage/
7
+ /InstalledFiles
8
+ /pkg/
9
+ /spec/reports/
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+
14
+ ## Specific to RubyMotion:
15
+ .dat*
16
+ .repl_history
17
+ build/
18
+
19
+ ## Documentation cache and generated files:
20
+ /.yardoc/
21
+ /_yardoc/
22
+ /doc/
23
+ /rdoc/
24
+
25
+ ## Environment normalisation:
26
+ /.bundle/
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ # Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # XSR - eXtremely Simple REST client
2
+
3
+ XSR is an extremely simple REST client aimed to use against JSON/REST APIs.
4
+
5
+ ## Installation
6
+
7
+ Simply run
8
+
9
+ ``` console
10
+ $ gem install xsr
11
+ ```
12
+
13
+ ### Using Rails?
14
+
15
+ Add the following line to your Gemfile:
16
+
17
+ ``` ruby
18
+ gem 'xsr'
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Create a new instance of XSR client specifying the base_url for wich you will be requesting further paths:
24
+
25
+ ``` ruby
26
+ require 'xsr'
27
+ client = XSR::Client.new
28
+ ```
29
+
30
+ And then invoke a service:
31
+
32
+ ``` ruby
33
+ resp = client.get('http://api.something.io')
34
+ resp.success?
35
+ #=> true
36
+ resp.body
37
+ #=> JSON response as a Ruby Hash Object
38
+ ```
39
+ ###Supported HTTP verbs
40
+ Implemented verbs are GET, POST, PUT and DELETE. To change the verb simply invoke the corresponding method:
41
+ ####HTTP GET
42
+ This will make a HTTP GET request to http://api.something.io
43
+ ``` ruby
44
+ client.get('http://api.something.io')
45
+ ```
46
+ ####HTTP POST
47
+ This will make a HTTP POST request to http://api.something.io
48
+ ``` ruby
49
+ client.post('http://api.something.io')
50
+ ```
51
+ ####HTTP PUT
52
+ This will make a HTTP PUT request to http://api.something.io
53
+ ``` ruby
54
+ client.put('http://api.something.io')
55
+ ```
56
+ ####HTTP DELETE
57
+ This will make a HTTP DELETE request to http://api.something.io
58
+ ``` ruby
59
+ client.delete('http://api.something.io')
60
+ ```
61
+
62
+ ###Using query string arguments
63
+ This will make a HTTP GET request to http://api.somthing.io?arg1=a&arg2=b
64
+ ``` ruby
65
+ client.get('http://api.something.io', args: {arg1: 'a', arg2: 'b'})
66
+ ```
67
+
68
+ ###Passing JSON arguments in request body
69
+ ``` ruby
70
+ req = { some_key: some_value, other_key: [1,2,3] }
71
+ client.post('http://api.something.io', body: req)
72
+ ```
73
+
74
+ ###Using HTTP headers
75
+ This will make a HTTP GET request to http://api.somthing.io passing 'Some-Header: Some-Value' in the HTTP headers
76
+ ``` ruby
77
+ resp = client.get('http://api.something.io', header: {some_header: 'some_value'})
78
+ ```
79
+
80
+ ###Response object
81
+ HTTP response comes in the form of a ```XSR::Response``` object:
82
+ ``` ruby
83
+ resp = client.post('http://api.something.io')
84
+
85
+ resp.success?
86
+ #=> Response status code is 2xx
87
+
88
+ resp.bad_request?
89
+ #=> Response status code is 403
90
+
91
+ resp.not_found?
92
+ #=> Response status code is 404
93
+
94
+ resp.server_error?
95
+ #=> Response status code is 500
96
+
97
+ resp.body
98
+ #=> JSON response as a Ruby Hash object
99
+ ```
100
+
101
+ ##What's next?
102
+ I'm not planning to add more features right now, but feel free to fork this repo and add any extra functionality you consider that should be included. Please, submit a PR with proposed changes or fixes.
103
+ Just keep in mind a minimalist paradigm (https://youtu.be/tXVr2E1vfmk).
104
+
data/lib/xsr.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'open-uri'
2
+ require 'net/http'
3
+ require 'multi_json'
4
+ require 'openssl'
5
+
6
+ require 'xsr/client'
7
+ require 'xsr/response'
data/lib/xsr/client.rb ADDED
@@ -0,0 +1,52 @@
1
+ module XSR
2
+ class Client
3
+ attr_accessor :base_url
4
+ attr_accessor :default_header
5
+
6
+ def initialize(options = {})
7
+ @base_url = options[:base_url]
8
+ @base_header = options[:header]
9
+ end
10
+
11
+ def post(path, options = {})
12
+ request_with_data(path, options) { |uri| Net::HTTP::Post.new(uri.to_s) }
13
+ end
14
+
15
+ def delete(path, options = {})
16
+ request_with_data(path, options) { |uri| Net::HTTP::Delete.new(uri.to_s) }
17
+ end
18
+
19
+ def put(path, options = {})
20
+ request_with_data(path, options) { |uri| Net::HTTP::Put.new(uri.to_s) }
21
+ end
22
+
23
+ def get(path, options = {})
24
+ request_with_data(path, options) { |uri| Net::HTTP::Get.new(uri.to_s) }
25
+ end
26
+
27
+ private
28
+ def request_with_data(path, options = {})
29
+ args = options[:args] && URI::encode( options[:args].map{|k,v| "#{k}=#{v}"}.join('&').to_s )
30
+ uri = URI( @base_url.to_s + path.to_s + '?' + args.to_s )
31
+
32
+ req = yield(uri)
33
+
34
+ # Set headers
35
+ req['Content-Type'] = 'application/json'
36
+ @base_header && @base_header.each{ |k,v| req[k] = v }
37
+ options[:header] && options[:header].each{ |k,v| req[k] = v }
38
+
39
+ # Set body
40
+ req.body = options[:body] && MultiJson.dump( options[:body] )
41
+
42
+ http_session = Net::HTTP.new(uri.host, uri.port)
43
+
44
+ if uri.scheme == 'https' # Requires SSL?
45
+ http_session.use_ssl = true
46
+ http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
47
+ end
48
+
49
+ XSR::Response.new( http_session.start{ |http| http.request(req) } )
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,31 @@
1
+ module XSR
2
+ class Response
3
+ attr_reader :http_response
4
+
5
+ def initialize(http_response)
6
+ @http_response = http_response
7
+ end
8
+
9
+ def success?
10
+ @http_response.is_a? Net::HTTPSuccess
11
+ end
12
+
13
+ def bad_request?
14
+ @http_response.is_a? Net::HTTPBadRequest
15
+ end
16
+
17
+ def not_found?
18
+ @http_response.is_a? Net::HTTPNotFound
19
+ end
20
+
21
+ def server_error?
22
+ @http_response.is_a? Net::HTTPServerError
23
+ end
24
+
25
+ def body
26
+ if self.success?
27
+ @http_response.body && MultiJson.load( @http_response.body, symbolize_keys: true )
28
+ end
29
+ end
30
+ end
31
+ end
data/makefile ADDED
@@ -0,0 +1,5 @@
1
+ .PHONY: test
2
+
3
+ test:
4
+ @echo Running tests... && \
5
+ RUBYLIB=./lib cutest test/*_test.rb
@@ -0,0 +1,68 @@
1
+ require 'xsr'
2
+ require_relative 'helper'
3
+
4
+ module ClientTest
5
+ prepare do
6
+ @client = XSR::Client.new( base_url: 'http://httpbin.org' )
7
+ end
8
+
9
+ test "get request" do
10
+ resp = @client.get('/get')
11
+
12
+ assert resp.http_response.instance_of?(Net::HTTPOK)
13
+ end
14
+
15
+ test "post request" do
16
+ req = {some_key: 'some_value'}
17
+ resp = @client.post( '/post', {body: req} )
18
+
19
+ assert resp.http_response.instance_of?(Net::HTTPOK)
20
+ assert_equal MultiJson.load(resp.http_response.body, symbolize_keys: true)[:json], req
21
+ end
22
+
23
+ test 'put request' do
24
+ req = {some_key: 'some_value'}
25
+ resp = @client.put( '/put', {body: req} )
26
+
27
+ assert resp.http_response.instance_of?(Net::HTTPOK)
28
+ assert_equal MultiJson.load(resp.http_response.body, symbolize_keys: true)[:json], req
29
+ end
30
+
31
+ test 'delete request' do
32
+ req = {some_key: 'some_value'}
33
+ resp = @client.delete( '/delete', {body: req} )
34
+
35
+ assert resp.http_response.instance_of?(Net::HTTPOK)
36
+ assert_equal MultiJson.load(resp.http_response.body, symbolize_keys: true)[:json], req
37
+ end
38
+
39
+ test 'headers are passed to request' do
40
+ h = { 'Some-Header' => 'some_value'}
41
+ resp = @client.get( '/headers', {header: h} )
42
+
43
+ assert resp.http_response.instance_of?(Net::HTTPOK)
44
+ assert_equal MultiJson.load(resp.http_response.body)['headers']['Some-Header'], 'some_value'
45
+ end
46
+
47
+ test 'default headers are passed to request' do
48
+ h = { 'Some-Header' => 'some_value'}
49
+ resp = XSR::Client.new(header: h).get( 'https://httpbin.org/headers' )
50
+
51
+ assert resp.http_response.instance_of?(Net::HTTPOK)
52
+ assert_equal MultiJson.load(resp.http_response.body)['headers']['Some-Header'], 'some_value'
53
+ end
54
+
55
+ test 'query string arguments are passed to request' do
56
+ p = {some_arg: 'some_value'}
57
+ resp = @client.get( '/get', {args: p} )
58
+ assert resp.http_response.instance_of?(Net::HTTPOK)
59
+
60
+ assert_equal MultiJson.load(resp.http_response.body)['args']['some_arg'], 'some_value'
61
+ end
62
+
63
+ test 'https request' do
64
+ resp = XSR::Client.new.get('https://httpbin.org/get')
65
+
66
+ assert resp.http_response.instance_of?(Net::HTTPOK)
67
+ end
68
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'securerandom'
2
+
3
+ def random_hash
4
+ {SecureRandom.hex => SecureRandom.hex}
5
+ end
6
+
@@ -0,0 +1,57 @@
1
+ require 'xsr'
2
+ require_relative 'helper'
3
+
4
+ module ResponseTest
5
+ prepare do
6
+ @client = XSR::Client.new( base_url: 'http://httpbin.org' )
7
+ end
8
+
9
+ test "status 200 is a successful response" do
10
+ resp = @client.get('/status/200')
11
+ assert resp.success?
12
+ end
13
+
14
+ test "status 201 is a successful response" do
15
+ resp = @client.get('/status/201')
16
+ assert resp.success?
17
+ end
18
+
19
+ test "status 202 is a successful response" do
20
+ resp = @client.get('/status/202')
21
+ assert resp.success?
22
+ end
23
+
24
+ test "status 400 is a successful response" do
25
+ resp = @client.get('/status/400')
26
+ assert !resp.success?
27
+ assert resp.bad_request?
28
+ end
29
+
30
+ test "status 404 is a successful response" do
31
+ resp = @client.get('/status/404')
32
+ assert !resp.success?
33
+ assert resp.not_found?
34
+ end
35
+
36
+ test "status 500 is a successful response" do
37
+ resp = @client.get('/status/500')
38
+ assert !resp.success?
39
+ assert resp.server_error?
40
+ end
41
+
42
+ test "simple body" do
43
+ req = {some_attrib: 'some_value'}
44
+ resp = @client.post('/post', body: req)
45
+
46
+ assert resp.success?
47
+ assert_equal resp.body[:json], req
48
+ end
49
+
50
+ test "body with nested attributes" do
51
+ req = {something: {some_attrib: 'some_value'}}
52
+ resp = @client.post('/post', body: req)
53
+
54
+ assert resp.success?
55
+ assert_equal resp.body[:json], req
56
+ end
57
+ end
data/xsr.gemspec ADDED
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'xsr'
3
+ s.version = '1.0.0'
4
+ s.summary = "XSR: eXtremely Simple REST Client"
5
+ s.description = "A very simple library to talk to a REST/JSON API"
6
+ s.authors = ["Matias Owsianik"]
7
+ s.email = ['matiasow@gmail.com']
8
+ s.homepage = 'http://github.com/matiasow/xsr'
9
+ s.license = 'MIT'
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_dependency "multi_json"
14
+ s.add_development_dependency "cutest"
15
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xsr
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matias Owsianik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cutest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A very simple library to talk to a REST/JSON API
42
+ email:
43
+ - matiasow@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - README.md
50
+ - lib/xsr.rb
51
+ - lib/xsr/client.rb
52
+ - lib/xsr/response.rb
53
+ - makefile
54
+ - test/client_test.rb
55
+ - test/helper.rb
56
+ - test/response_test.rb
57
+ - xsr.gemspec
58
+ homepage: http://github.com/matiasow/xsr
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.4.5
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: 'XSR: eXtremely Simple REST Client'
82
+ test_files: []