haipa 0.0.2 → 0.0.3
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.
- data/README.md +66 -1
- data/haipa.gemspec +1 -0
- data/lib/haipa.rb +2 -0
- data/lib/haipa/api.rb +10 -11
- data/lib/haipa/embedded.rb +40 -0
- data/lib/haipa/links.rb +11 -7
- data/lib/haipa/resource.rb +32 -7
- data/lib/haipa/version.rb +1 -1
- data/spec/haipa/api_spec.rb +5 -5
- data/spec/haipa/resource_spec.rb +25 -1
- metadata +5 -4
data/README.md
CHANGED
@@ -18,7 +18,72 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
Haipa.api creates a new Haipa::Api object. The initializer's parameters and block
|
22
|
+
are passed straight through to Faraday's connection initializer so you have full
|
23
|
+
access to all of Faraday's settings, including adapter and middlewares.
|
24
|
+
|
25
|
+
At the moment the only additions Haipa makes to the Faraday default is to add
|
26
|
+
the accepts header application/hal+json and the user agent header Haipa. This
|
27
|
+
defaults are deep merged with the settings passed to the initializer so they can
|
28
|
+
be overridden.
|
29
|
+
|
30
|
+
Given a API root description
|
31
|
+
|
32
|
+
{
|
33
|
+
"_links" :
|
34
|
+
{
|
35
|
+
"self" : { "href" : "/api/v1" },
|
36
|
+
"things" : { "href" : "/api/v1/things" }
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
and a thing index resource
|
41
|
+
|
42
|
+
{
|
43
|
+
"_embedded" : {
|
44
|
+
"things" => [
|
45
|
+
{
|
46
|
+
"name" => "thing1",
|
47
|
+
"_links" : { "self" : { "href" : "/api/v1/things/thing1" } }
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"name" => "thing2",
|
51
|
+
"_links" : { "self" : { "href" : "/api/v1/things/thing2" } }
|
52
|
+
}
|
53
|
+
]
|
54
|
+
},
|
55
|
+
"_links" : {
|
56
|
+
"self" : { "href" : "/api/v1/things" }
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
Then Haipa can consume this API with
|
61
|
+
|
62
|
+
api = Haipa.api(url:'http://localhost:3000/api/v1')
|
63
|
+
api.resource # the root as a Haipa::Resource
|
64
|
+
api.description # alias of api.resource
|
65
|
+
api.links # the root links as a Haipa::Links
|
66
|
+
api.href # the uri of the root
|
67
|
+
api.embedded # the embedded resource array Haipa::Embedded
|
68
|
+
api.resources # alias of api.embedded
|
69
|
+
api.to_hash # the api root as a hash
|
70
|
+
|
71
|
+
links = api.links
|
72
|
+
links.things # the things Haipa::Resource
|
73
|
+
links.to_hash # the links as a hash
|
74
|
+
|
75
|
+
things = links.things # things Haipa::Resource
|
76
|
+
things.links # the things index Haipa::Links
|
77
|
+
things.embedded # the things index Haipa::Embedded
|
78
|
+
things.to_hash # the things resource as a hash
|
79
|
+
|
80
|
+
embedded = things.embedded
|
81
|
+
embedded.things # array of Haipa::Resource
|
82
|
+
embedded.things.first # the first embedded thing Haipa::Resource
|
83
|
+
embedded.things.first.name # the first embedded thing Haipa::Resource name
|
84
|
+
embedded.things[1] # the second embedded thing Haipa::Resource
|
85
|
+
embedded.things.first.clear.other_attribute
|
86
|
+
embedded.to_hash # the embedded resources as a hash
|
22
87
|
|
23
88
|
## Contributing
|
24
89
|
|
data/haipa.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'faraday', '~> 0.8'
|
22
22
|
spec.add_runtime_dependency 'hashie', '~> 2.0.0'
|
23
|
+
# spec.add_runtime_dependency 'uri_templates', '~> 0.2.0'
|
23
24
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
25
|
spec.add_development_dependency 'rake'
|
25
26
|
spec.add_development_dependency 'rspec', '~> 2.13.0'
|
data/lib/haipa.rb
CHANGED
data/lib/haipa/api.rb
CHANGED
@@ -3,13 +3,14 @@ module Haipa
|
|
3
3
|
extend Forwardable
|
4
4
|
|
5
5
|
attr_reader :conn, :resource, :uri
|
6
|
-
def_delegators :@conn, :get
|
7
|
-
def_delegators :@resource, :links, :embedded, :href
|
6
|
+
def_delegators :@conn, :get, :post, :put, :delete
|
7
|
+
def_delegators :@resource, :links, :embedded, :href, :resources, :to_hash
|
8
8
|
alias :connection :conn
|
9
|
+
alias :description :resource
|
9
10
|
|
10
11
|
def initialize(params={})
|
11
12
|
@uri = URI(params[:url].to_s).path
|
12
|
-
@conn = Faraday.new(defaults.
|
13
|
+
@conn = Faraday.new(defaults.deep_merge(params)) do |conn|
|
13
14
|
yield conn if block_given?
|
14
15
|
end
|
15
16
|
@resource = Resource.new(self,'')
|
@@ -19,18 +20,16 @@ module Haipa
|
|
19
20
|
{
|
20
21
|
:headers =>
|
21
22
|
{
|
22
|
-
|
23
|
-
|
23
|
+
'Accept' => 'application/hal+json',
|
24
|
+
'UserAgent' => 'Haipa',
|
25
|
+
'Content-Type' => 'application/hal+json'
|
24
26
|
}
|
25
|
-
}
|
27
|
+
}.extend(Hashie::Extensions::DeepMerge)
|
26
28
|
end
|
27
29
|
|
28
30
|
def clear
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def description
|
33
|
-
resource.get
|
31
|
+
resource.clear
|
32
|
+
self
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Haipa
|
2
|
+
class Embedded
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
attr_reader :resource
|
6
|
+
def_delegators :@data, :empty?, :has_key?, :fetch
|
7
|
+
|
8
|
+
def initialize(resource, data)
|
9
|
+
@data = data
|
10
|
+
@resource = resource
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(name, *args, &block)
|
14
|
+
if @data.has_key?(name)
|
15
|
+
from_array(@data[name])
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
@data
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def from_array(array_or_hash)
|
28
|
+
if array_or_hash.kind_of?(Array)
|
29
|
+
array_or_hash.map{ |e| from_hash(e) }
|
30
|
+
else
|
31
|
+
from_hash(array_or_hash)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def from_hash(hash)
|
36
|
+
uri = hash.fetch('_links',{}).fetch('self',{}).fetch('href',nil)
|
37
|
+
Resource.new(resource.api, uri, hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/haipa/links.rb
CHANGED
@@ -2,17 +2,21 @@ module Haipa
|
|
2
2
|
class Links
|
3
3
|
extend Forwardable
|
4
4
|
|
5
|
-
attr_reader :
|
6
|
-
def_delegators :@
|
5
|
+
attr_reader :resource
|
6
|
+
def_delegators :@data, :empty?, :has_key?
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@
|
8
|
+
def initialize(resource, data)
|
9
|
+
@data = data
|
10
|
+
@resource = resource
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
@data
|
11
15
|
end
|
12
16
|
|
13
17
|
def method_missing(name, *args, &block)
|
14
|
-
if
|
15
|
-
Resource.new(
|
18
|
+
if @data.has_key?(name)
|
19
|
+
Resource.new(resource.api, @data[name]['href'])
|
16
20
|
else
|
17
21
|
super
|
18
22
|
end
|
data/lib/haipa/resource.rb
CHANGED
@@ -2,30 +2,55 @@ module Haipa
|
|
2
2
|
class Resource
|
3
3
|
attr_reader :api, :uri
|
4
4
|
|
5
|
-
def initialize(api, uri)
|
5
|
+
def initialize(api, uri, data=nil)
|
6
6
|
@api = api
|
7
7
|
@uri = uri
|
8
|
-
|
8
|
+
@data = ::Hashie::Mash.new(data) if data
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
get
|
9
13
|
end
|
10
14
|
|
11
15
|
def clear
|
12
|
-
@
|
16
|
+
@data = nil
|
17
|
+
self
|
13
18
|
end
|
14
19
|
|
15
20
|
def get
|
16
|
-
|
21
|
+
return {} unless uri
|
22
|
+
@data ||= ::Hashie::Mash.new(JSON.parse(api.get(uri).body))
|
23
|
+
end
|
24
|
+
|
25
|
+
def post(params={})
|
26
|
+
api.post(uri, params) do |req|
|
27
|
+
yield req if block_given?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def put(params={})
|
32
|
+
api.put(uri, params) do |req|
|
33
|
+
yield req if block_given?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(params={})
|
38
|
+
api.delete(uri, params) do |req|
|
39
|
+
yield req if block_given?
|
40
|
+
end
|
17
41
|
end
|
18
42
|
|
19
43
|
def embedded
|
20
|
-
get.fetch('_embedded', {})
|
44
|
+
@embedded ||= Embedded.new(self, get.fetch('_embedded', {}))
|
21
45
|
end
|
46
|
+
alias :resources :embedded
|
22
47
|
|
23
48
|
def links
|
24
|
-
Links.new(self, get.fetch('_links', {}))
|
49
|
+
@links ||= Links.new(self, get.fetch('_links', {}))
|
25
50
|
end
|
26
51
|
|
27
52
|
def href
|
28
|
-
(links.self || {}).fetch('href', nil)
|
53
|
+
(links.to_hash.self || {}).fetch('href', nil)
|
29
54
|
end
|
30
55
|
end
|
31
56
|
end
|
data/lib/haipa/version.rb
CHANGED
data/spec/haipa/api_spec.rb
CHANGED
@@ -8,10 +8,10 @@ describe Haipa::Api do
|
|
8
8
|
stub.get('/') { [200, {}, description.to_json] }
|
9
9
|
end
|
10
10
|
end
|
11
|
-
subject { Haipa.api { |
|
11
|
+
subject { Haipa.api { |conn| conn.adapter :test, stubs } }
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
specify { subject.description.to_hash.should == description }
|
14
|
+
specify { subject.links.to_hash.should == description['_links'] }
|
15
|
+
specify { subject.embedded.to_hash.should == description['_embedded'] }
|
16
|
+
specify { subject.href.should == description['_links']['self']['href'] }
|
17
17
|
end
|
data/spec/haipa/resource_spec.rb
CHANGED
@@ -3,13 +3,37 @@ require_relative '../spec_helper'
|
|
3
3
|
describe Haipa::Resource do
|
4
4
|
let(:uri) { '/api/v1' }
|
5
5
|
let(:response) { double('response', body:body.to_json) }
|
6
|
-
let(:api) { double('api',
|
6
|
+
let(:api) { double('api', get:response) }
|
7
7
|
subject { Haipa::Resource.new(api, uri) }
|
8
8
|
|
9
9
|
context "with minimum response" do
|
10
10
|
let(:body) { {'_embedded' => {}, '_links' => {'self' => {'href' => uri}}} }
|
11
11
|
its(:embedded) { should be_empty }
|
12
|
+
its(:resources) { should be_empty }
|
12
13
|
its(:links) { should_not be_empty }
|
13
14
|
specify { subject.links.self.should be }
|
14
15
|
end
|
16
|
+
|
17
|
+
context "with embedded resources" do
|
18
|
+
let(:body) do
|
19
|
+
{
|
20
|
+
'_embedded' => {
|
21
|
+
'things' => [{
|
22
|
+
'name'=>'thing',
|
23
|
+
'_links' => {'self' => {'href' => uri+'/things/1'}}
|
24
|
+
}],
|
25
|
+
'thing'=>{
|
26
|
+
'name'=>'thing',
|
27
|
+
'_links' => {'self' => {'href' => uri+'/things/1'}}
|
28
|
+
}
|
29
|
+
},
|
30
|
+
'_links' => {'self' => {'href' => uri}}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
specify { subject.embedded.should_not be_empty }
|
34
|
+
specify { subject.resources.thing.should be_a Haipa::Resource }
|
35
|
+
specify { subject.resources.things.first.should be_a Haipa::Resource }
|
36
|
+
specify { subject.resources.thing.get.name.should be == 'thing' }
|
37
|
+
specify { subject.resources.things.first.get.name.should be == 'thing' }
|
38
|
+
end
|
15
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haipa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- haipa.gemspec
|
108
108
|
- lib/haipa.rb
|
109
109
|
- lib/haipa/api.rb
|
110
|
+
- lib/haipa/embedded.rb
|
110
111
|
- lib/haipa/links.rb
|
111
112
|
- lib/haipa/resource.rb
|
112
113
|
- lib/haipa/version.rb
|
@@ -129,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
130
|
version: '0'
|
130
131
|
segments:
|
131
132
|
- 0
|
132
|
-
hash: -
|
133
|
+
hash: -2840839347400538447
|
133
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
135
|
none: false
|
135
136
|
requirements:
|
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
139
|
version: '0'
|
139
140
|
segments:
|
140
141
|
- 0
|
141
|
-
hash: -
|
142
|
+
hash: -2840839347400538447
|
142
143
|
requirements: []
|
143
144
|
rubyforge_project:
|
144
145
|
rubygems_version: 1.8.23
|