xsr 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|