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 CHANGED
@@ -18,7 +18,72 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
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
 
@@ -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'
@@ -1,11 +1,13 @@
1
1
  require 'uri'
2
2
  require 'forwardable'
3
3
  require 'hashie'
4
+ require 'faraday'
4
5
 
5
6
  require 'haipa/version'
6
7
  require 'haipa/api'
7
8
  require 'haipa/resource'
8
9
  require 'haipa/links'
10
+ require 'haipa/embedded'
9
11
 
10
12
  module Haipa
11
13
  def self.api(params={})
@@ -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.merge(params)) do |conn|
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
- :accept => 'application/hal+json',
23
- :user_agent => 'Haipa'
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
- @resource = nil
30
- end
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
@@ -2,17 +2,21 @@ module Haipa
2
2
  class Links
3
3
  extend Forwardable
4
4
 
5
- attr_reader :links, :parent
6
- def_delegators :@links, :empty?
5
+ attr_reader :resource
6
+ def_delegators :@data, :empty?, :has_key?
7
7
 
8
- def initialize(parent, links)
9
- @links = links
10
- @parent = parent
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 links.has_key?(name)
15
- Resource.new(parent.api, links[name][:href])
18
+ if @data.has_key?(name)
19
+ Resource.new(resource.api, @data[name]['href'])
16
20
  else
17
21
  super
18
22
  end
@@ -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
- clear
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
- @get = nil
16
+ @data = nil
17
+ self
13
18
  end
14
19
 
15
20
  def get
16
- @get ||= ::Hashie::Mash.new(JSON.parse(api.get(uri).body))
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
@@ -1,3 +1,3 @@
1
1
  module Haipa
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -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 { |builder| builder.adapter :test, stubs } }
11
+ subject { Haipa.api { |conn| conn.adapter :test, stubs } }
12
12
 
13
- its(:description) { should eq(description) }
14
- its(:links) { should eq(description['_links']) }
15
- its(:embedded) { should eq(description['_embedded']) }
16
- its(:href) { should eq(description['_links']['self']['href']) }
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
@@ -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', relative_get:response) }
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.2
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-23 00:00:00.000000000 Z
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: -2396805276847003605
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: -2396805276847003605
142
+ hash: -2840839347400538447
142
143
  requirements: []
143
144
  rubyforge_project:
144
145
  rubygems_version: 1.8.23