braque 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e8bbfc9dc19e8eb3f4130366f9aa757bbb122ae
4
- data.tar.gz: e574170f094b58b9f624a04461986978cd35de83
3
+ metadata.gz: a4c1ebc21906dfa95cf2c91d86d5280cb674798e
4
+ data.tar.gz: 21240b5b4080d20712490a9be9f2f8785e2a7fd3
5
5
  SHA512:
6
- metadata.gz: 8900c7e630a9e9a68c0ed67141895543205949bae1dde1192c543821b8394c75bf9922298449886120ae558f25c0a58243040fd372ccd859770e8ebf54bd94b2
7
- data.tar.gz: 6ea404e052ea8412412635cc5d1abba74ae5a270ca29d0e8ab621d3a342f18d91db2e46a7e99bba928fe7780889e665e675dbce6bf51c571af99a7eb9e73ad6e
6
+ metadata.gz: e75f45268a9392bbaf483483d779e9e7f25467cf9bb18f70cd7da537e76cb10c176be63c82d87f8e80863be1d442a5b013d532ea87f9de96ea3bbcee0517f54c
7
+ data.tar.gz: 50a7a00106e3e8c6b5b723aee03ec9f3060ac619442d2a891de756a67d2ce6cdbd66cd6f8f39e2e6c822676837f3edd97bd8b686487cf823fcdd709350b01d03
data/README.md CHANGED
@@ -2,19 +2,18 @@
2
2
 
3
3
  Braque aims to provide a simple and familiar interface for setting up clients to interact with [Hypermedia (hal+json)](http://stateless.co/hal_specification.html) API services. It is a lightweight wrapper around [Hyperclient](https://github.com/codegram/hyperclient) and [ActiveAttr](https://github.com/cgriego/active_attr).
4
4
 
5
- Braque is an early-stage and exploratory project.
5
+ Braque is an early-stage and exploratory project. That said, at [Artsy](https://www.artsy.net), we've used Braque to consume [Gris](https://github.com/artsy/gris) APIs with great benefit.
6
6
 
7
7
  [![Build Status](https://semaphoreci.com/api/v1/projects/c557a59e-1c1a-4719-a41a-6462a424ddfa/381676/badge.png)](https://semaphoreci.com/dylanfareed/braque)
8
8
 
9
9
  ### Model setup
10
10
 
11
- ```Braque::Model``` is ActiveSupport concern. You can use Braque::Model to map a remote resource to a class in your application. Do so by including Braque::Model in the class, defining the API service's root url and authentication details, and listing attributes which we expect from the API.
11
+ ```Braque::Model``` is ActiveSupport concern. You can use Braque::Model to map a remote resource to a class in your application. Do so by including Braque::Model in the class, defining the API service's root url, and listing attributes which we expect to receive from the API.
12
12
 
13
13
  ```ruby
14
14
  class Article
15
15
  include Braque::Model
16
- self.api_root = Rails.application.config_for(:article_service)['url']
17
- self.api_token = Rails.application.config_for(:article_service)['token']
16
+ self.api_root = Rails.application.config_for(:articles_service)['url']
18
17
 
19
18
  attribute :id
20
19
  attribute :title
@@ -25,7 +24,39 @@ class Article
25
24
  end
26
25
  ```
27
26
 
28
- In a Rails app, you can then use this model simply:
27
+ ### Credentials
28
+
29
+ ```Braque::Model``` also supports multiple API authentication strategies. Defining `http_authorization_header` or `accept_header` with the model will pass those credentials to the provider API with each request.
30
+
31
+ For example, `http_authorization_header` credentials defined here are added to the request's `Http-Authorization` headers.
32
+
33
+ ```ruby
34
+ class Article
35
+ include Braque::Model
36
+ self.api_root = Rails.application.config_for(:articles_service)['url']
37
+ self.http_authorization_header = Rails.application.config_for(:articles_service)['token']
38
+
39
+ attribute :id
40
+ attribute :title
41
+ end
42
+ ```
43
+
44
+ Defining an `accept_header` credential will replace Hyperclient's default `Accept` header with the value you provide.
45
+
46
+ ```ruby
47
+ class Article
48
+ include Braque::Model
49
+ self.api_root = Rails.application.config_for(:articles_service)['url']
50
+ self.accept_header = Rails.application.config_for(:articles_service)['accept_header']
51
+
52
+ attribute :id
53
+ attribute :title
54
+ end
55
+ ```
56
+
57
+ ### Controllers
58
+
59
+ In a Rails app, once you've set up your model, you can use the following familiar syntax to query the remote API:
29
60
 
30
61
  ```ruby
31
62
  class ArticlesController < ApplicationController
data/lib/braque/model.rb CHANGED
@@ -4,9 +4,12 @@ module Braque
4
4
  include ::ActiveAttr::Model
5
5
 
6
6
  included do
7
- class_attribute :api_root
8
- class_attribute :api_token
9
- class_attribute :accept_header
7
+ # NOTE: This adds class attributes to Braque::Model that will be
8
+ # used to set up Hyperclient in the client method.
9
+ #
10
+ [:api_root, :accept_header, :authorization_header, :http_authorization_header].each do |sym|
11
+ class_attribute sym
12
+ end
10
13
 
11
14
  # NOTE: This assumes that the related API uses an ID attribute to
12
15
  # define the resource. Rails will use this field to construct
@@ -31,7 +34,8 @@ module Braque
31
34
  end
32
35
 
33
36
  def save(params = {})
34
- response = self.class.client.method(self.class.instance_method_name).call(resource_find_options)._patch("#{self.class.instance_method_name}" => params)
37
+ response = self.class.client.method(self.class.instance_method_name).call(resource_find_options)
38
+ ._patch("#{self.class.instance_method_name}" => params)
35
39
  self.class.new response
36
40
  end
37
41
 
@@ -87,7 +91,8 @@ module Braque
87
91
 
88
92
  def client
89
93
  Hyperclient.new(api_root) do |client|
90
- client.headers['Http-Authorization'] = api_token if api_token
94
+ client.headers['Http-Authorization'] = http_authorization_header if http_authorization_header
95
+ client.headers['Authorization'] = authorization_header if authorization_header
91
96
  client.headers['Accept'] = accept_header if accept_header
92
97
  end
93
98
  end
@@ -1,3 +1,3 @@
1
1
  module Braque
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
@@ -11,14 +11,14 @@ RSpec.describe 'Hyperclient header configuration' do
11
11
  class Mantle
12
12
  include ::Braque::Model
13
13
  self.api_root = 'http://localhost:9292'
14
- self.api_token = 'replace-me'
14
+ self.http_authorization_header = 'replace-me'
15
15
  end
16
16
 
17
- it 'passes api_token via Http-Authorization headers with requests' do
17
+ it 'passes http_authorization_header via Http-Authorization headers with requests' do
18
18
  Mantle.client._get
19
19
  expect(
20
20
  root_request
21
- .with(headers: { 'Http-Authorization' => Mantle.api_token })
21
+ .with(headers: { 'Http-Authorization' => Mantle.http_authorization_header })
22
22
  ).to have_been_requested
23
23
  end
24
24
 
@@ -46,4 +46,20 @@ RSpec.describe 'Hyperclient header configuration' do
46
46
  ).to have_been_requested
47
47
  end
48
48
  end
49
+
50
+ context 'with a Braque::Model class that defines an authorization header' do
51
+ class Lithoshpere
52
+ include ::Braque::Model
53
+ self.api_root = 'http://localhost:9292'
54
+ self.authorization_header = 'Farallon Plate'
55
+ end
56
+
57
+ it 'includes correct Authorization header with request headers' do
58
+ Lithoshpere.client._get
59
+ expect(
60
+ root_request
61
+ .with(headers: { 'Authorization' => Lithoshpere.authorization_header })
62
+ ).to have_been_requested
63
+ end
64
+ end
49
65
  end
@@ -11,7 +11,7 @@ RSpec.describe Braque::Helpers::HypermediaResponsesHelper do
11
11
  class Article
12
12
  include ::Braque::Model
13
13
  self.api_root = 'http://localhost:9292'
14
- self.api_token = 'replace-me'
14
+ self.http_authorization_header = 'replace-me'
15
15
  attribute :id
16
16
  attribute :title
17
17
  attribute :key
@@ -5,7 +5,7 @@ RSpec.describe Braque::Model, type: :model do
5
5
  class Breeze
6
6
  include ::Braque::Model
7
7
  self.api_root = 'http://localhost:9292'
8
- self.api_token = 'replace-me'
8
+ self.http_authorization_header = 'replace-me'
9
9
  self.accept_header = 'application/vnd.el-nino-v1+json'
10
10
  attribute :id
11
11
  attribute :title
@@ -20,14 +20,14 @@ RSpec.describe Braque::Model, type: :model do
20
20
 
21
21
  let(:root_request) do
22
22
  WebMock.stub_request(:get, "#{Breeze.api_root}/")
23
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
23
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
24
24
  .with(headers: { 'Accept' => Breeze.accept_header })
25
25
  .to_return(status: 200, body: root_response)
26
26
  end
27
27
 
28
28
  let(:root_request_with_token_resource_path) do
29
29
  WebMock.stub_request(:get, "#{Breeze.api_root}/")
30
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
30
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
31
31
  .with(headers: { 'Accept' => Breeze.accept_header })
32
32
  .to_return(status: 200, body: root_response_with_token_resource_path)
33
33
  end
@@ -50,7 +50,7 @@ RSpec.describe Braque::Model, type: :model do
50
50
  before(:each) do
51
51
  root_request
52
52
  @collection_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes")
53
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
53
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
54
54
  .with(headers: { 'Accept' => Breeze.accept_header })
55
55
  .to_return(status: 200, body: collection_response)
56
56
  @breezes = Breeze.list
@@ -80,7 +80,7 @@ RSpec.describe Braque::Model, type: :model do
80
80
  before(:each) do
81
81
  root_request
82
82
  @collection_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes")
83
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
83
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
84
84
  .with(headers: { 'Accept' => Breeze.accept_header })
85
85
  .to_return(status: 500)
86
86
  end
@@ -96,7 +96,7 @@ RSpec.describe Braque::Model, type: :model do
96
96
  before(:each) do
97
97
  root_request
98
98
  @collection_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes")
99
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
99
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
100
100
  .with(headers: { 'Accept' => Breeze.accept_header })
101
101
  .with(query: 'ids%5B0%5D=1&ids%5B1%5D=2')
102
102
  .to_return(status: 200, body: collection_response)
@@ -113,7 +113,7 @@ RSpec.describe Braque::Model, type: :model do
113
113
  before(:each) do
114
114
  root_request
115
115
  @resource_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes/1")
116
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
116
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
117
117
  .with(headers: { 'Accept' => Breeze.accept_header })
118
118
  .to_return(status: 200, body: resource_response)
119
119
  @breeze = Breeze.find(id: 1)
@@ -136,7 +136,7 @@ RSpec.describe Braque::Model, type: :model do
136
136
  before(:each) do
137
137
  root_request
138
138
  @resource_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes/1")
139
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
139
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
140
140
  .with(headers: { 'Accept' => Breeze.accept_header })
141
141
  .to_return(status: 500)
142
142
  end
@@ -158,7 +158,7 @@ RSpec.describe Braque::Model, type: :model do
158
158
 
159
159
  root_request_with_token_resource_path
160
160
  @resource_request = WebMock.stub_request(:get, "#{Breeze.api_root}/breezes/1?token=123")
161
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
161
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
162
162
  .with(headers: { 'Accept' => Breeze.accept_header })
163
163
  .to_return(status: 200, body: resource_response)
164
164
  @breeze = Breeze.find(id: 1, token: 123)
@@ -185,7 +185,7 @@ RSpec.describe Braque::Model, type: :model do
185
185
  before(:each) do
186
186
  root_request
187
187
  @create_request = WebMock.stub_request(:post, "#{Breeze.api_root}/breezes")
188
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
188
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
189
189
  .with(headers: { 'Accept' => Breeze.accept_header })
190
190
  .to_return(status: 201, body: resource_response)
191
191
  @params = { title: 'What a nice breeze.' }
@@ -210,7 +210,7 @@ RSpec.describe Braque::Model, type: :model do
210
210
  before(:each) do
211
211
  root_request
212
212
  @create_request = WebMock.stub_request(:post, "#{Breeze.api_root}/breezes")
213
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
213
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
214
214
  .with(headers: { 'Accept' => Breeze.accept_header })
215
215
  .to_return(status: 500)
216
216
  end
@@ -233,7 +233,7 @@ RSpec.describe Braque::Model, type: :model do
233
233
  before(:each) do
234
234
  root_request
235
235
  @save_request = WebMock.stub_request(:patch, "#{Breeze.api_root}/breezes/1")
236
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
236
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
237
237
  .with(headers: { 'Accept' => Breeze.accept_header })
238
238
  .to_return(status: 200, body: resource_response)
239
239
  @params = { title: 'What a nice breeze.' }
@@ -258,7 +258,7 @@ RSpec.describe Braque::Model, type: :model do
258
258
  before(:each) do
259
259
  root_request
260
260
  @save_request = WebMock.stub_request(:patch, "#{Breeze.api_root}/breezes/1")
261
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
261
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
262
262
  .with(headers: { 'Accept' => Breeze.accept_header })
263
263
  .to_return(status: 500)
264
264
  end
@@ -281,7 +281,7 @@ RSpec.describe Braque::Model, type: :model do
281
281
 
282
282
  root_request_with_token_resource_path
283
283
  @save_request = WebMock.stub_request(:patch, "#{Breeze.api_root}/breezes/1?token=123")
284
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
284
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
285
285
  .with(headers: { 'Accept' => Breeze.accept_header })
286
286
  .to_return(status: 200, body: resource_response)
287
287
  @params = { title: 'What a nice breeze.' }
@@ -312,7 +312,7 @@ RSpec.describe Braque::Model, type: :model do
312
312
  before(:each) do
313
313
  root_request
314
314
  @destroy_request = WebMock.stub_request(:delete, "#{Breeze.api_root}/breezes/1")
315
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
315
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
316
316
  .with(headers: { 'Accept' => Breeze.accept_header })
317
317
  .to_return(status: 200)
318
318
  @breeze = Breeze.new(id: 1).destroy
@@ -329,7 +329,7 @@ RSpec.describe Braque::Model, type: :model do
329
329
  before(:each) do
330
330
  root_request
331
331
  @destroy_request = WebMock.stub_request(:delete, "#{Breeze.api_root}/breezes/1")
332
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
332
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
333
333
  .with(headers: { 'Accept' => Breeze.accept_header })
334
334
  .to_return(status: 500)
335
335
  end
@@ -352,7 +352,7 @@ RSpec.describe Braque::Model, type: :model do
352
352
 
353
353
  root_request_with_token_resource_path
354
354
  @destroy_request = WebMock.stub_request(:delete, "#{Breeze.api_root}/breezes/1?token=123")
355
- .with(headers: { 'Http-Authorization' => Breeze.api_token })
355
+ .with(headers: { 'Http-Authorization' => Breeze.http_authorization_header })
356
356
  .with(headers: { 'Accept' => Breeze.accept_header })
357
357
  .to_return(status: 200)
358
358
  @breeze = Breeze.new(id: 1, token: 123).destroy
@@ -6,21 +6,21 @@ RSpec.describe Braque::Model, type: :model do
6
6
  class Wind
7
7
  include ::Braque::Model
8
8
  self.api_root = 'http://localhost:9292'
9
- self.api_token = 'replace-me'
9
+ self.http_authorization_header = 'replace-me'
10
10
  end
11
11
 
12
12
  class Tide
13
13
  include ::Braque::Model
14
14
  self.api_root = 'http://localhost:9393'
15
- self.api_token = 'do-replace-me-as-well'
15
+ self.http_authorization_header = 'do-replace-me-as-well'
16
16
  end
17
17
  end
18
18
 
19
- it 'sets the correct api_root and api_token for each class' do
19
+ it 'sets the correct api_root and http_authorization_header for each class' do
20
20
  expect(Tide.api_root).to eq 'http://localhost:9393'
21
- expect(Tide.api_token).to eq 'do-replace-me-as-well'
21
+ expect(Tide.http_authorization_header).to eq 'do-replace-me-as-well'
22
22
  expect(Wind.api_root).to eq 'http://localhost:9292'
23
- expect(Wind.api_token).to eq 'replace-me'
23
+ expect(Wind.http_authorization_header).to eq 'replace-me'
24
24
  end
25
25
  end
26
26
  end
@@ -6,7 +6,7 @@ RSpec.describe Braque::Model, type: :model do
6
6
  class GeologicModel
7
7
  include ::Braque::Model
8
8
  self.api_root = 'http://localhost:9292'
9
- self.api_token = 'replace-me'
9
+ self.http_authorization_header = 'replace-me'
10
10
  end
11
11
 
12
12
  class ContinentalDrift < GeologicModel
@@ -14,32 +14,32 @@ RSpec.describe Braque::Model, type: :model do
14
14
 
15
15
  class Convection < GeologicModel
16
16
  self.api_root = 'http://localhost:9595'
17
- self.api_token = 'ok-another-one-to-replace'
17
+ self.http_authorization_header = 'ok-another-one-to-replace'
18
18
  end
19
19
 
20
20
  class SeafloorSpreading
21
21
  include ::Braque::Model
22
22
  self.api_root = 'http://localhost:9393'
23
- self.api_token = 'do-replace-me-as-well'
23
+ self.http_authorization_header = 'do-replace-me-as-well'
24
24
  end
25
25
  end
26
26
 
27
27
  context 'api configuration' do
28
28
  it 'sets the correct api_root and api_token for the base class' do
29
29
  expect(GeologicModel.api_root).to eq 'http://localhost:9292'
30
- expect(GeologicModel.api_token).to eq 'replace-me'
30
+ expect(GeologicModel.http_authorization_header).to eq 'replace-me'
31
31
  end
32
32
  it 'sets the correct api_root and api_token for a subclassed class' do
33
33
  expect(ContinentalDrift.api_root).to eq 'http://localhost:9292'
34
- expect(ContinentalDrift.api_token).to eq 'replace-me'
34
+ expect(ContinentalDrift.http_authorization_header).to eq 'replace-me'
35
35
  end
36
36
  it 'sets the correct api_root and api_token for a subclassed class with variable overrides' do
37
37
  expect(Convection.api_root).to eq 'http://localhost:9595'
38
- expect(Convection.api_token).to eq 'ok-another-one-to-replace'
38
+ expect(Convection.http_authorization_header).to eq 'ok-another-one-to-replace'
39
39
  end
40
40
  it 'sets the correct api_root and api_token for a new Braque::Model class' do
41
41
  expect(SeafloorSpreading.api_root).to eq 'http://localhost:9393'
42
- expect(SeafloorSpreading.api_token).to eq 'do-replace-me-as-well'
42
+ expect(SeafloorSpreading.http_authorization_header).to eq 'do-replace-me-as-well'
43
43
  end
44
44
  end
45
45
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braque
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Fareed
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-03 00:00:00.000000000 Z
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hyperclient
@@ -99,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  version: '0'
100
100
  requirements: []
101
101
  rubyforge_project:
102
- rubygems_version: 2.4.8
102
+ rubygems_version: 2.4.3
103
103
  signing_key:
104
104
  specification_version: 4
105
105
  summary: Braque provides a simple interface for interacting with Hypermedia API services