braque 0.1.4 → 0.1.5

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