xsr 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/README.md +104 -0
- data/lib/xsr.rb +7 -0
- data/lib/xsr/client.rb +52 -0
- data/lib/xsr/response.rb +31 -0
- data/makefile +5 -0
- data/test/client_test.rb +68 -0
- data/test/helper.rb +6 -0
- data/test/response_test.rb +57 -0
- data/xsr.gemspec +15 -0
- metadata +82 -0
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
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
|
data/lib/xsr/response.rb
ADDED
@@ -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
data/test/client_test.rb
ADDED
@@ -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,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: []
|