Skip to content

Commit fc9af92

Browse files
committed
Add basic support for GlobalId
1 parent 55e8a81 commit fc9af92

File tree

6 files changed

+108
-2
lines changed

6 files changed

+108
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### 0.9.2 (Next)
44

5+
* [#150](https://github.com/codegram/hyperclient/pull/150): Add better support for globalid and active job - [@yuki24](https://github.com/yuki24).
56
* Your contribution here.
67

78
### 0.9.1 (2019/08/25)

hyperclient.gemspec

+2
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ Gem::Specification.new do |gem|
1919
gem.add_dependency 'faraday_hal_middleware'
2020
gem.add_dependency 'faraday_middleware'
2121
gem.add_dependency 'net-http-digest_auth'
22+
23+
gem.add_development_dependency 'globalid'
2224
end

lib/hyperclient.rb

+8-1
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@
77
require 'hyperclient/resource'
88
require 'hyperclient/resource_collection'
99
require 'hyperclient/version'
10+
require 'hyperclient/railtie' if defined?(Rails)
1011

1112
# Public: Hyperclient namespace.
1213
#
1314
module Hyperclient
15+
URL_TO_ENDPOINT_MAPPING = { }
16+
1417
# Public: Convenience method to create new EntryPoints.
1518
#
1619
# url - A String with the url of the API.
1720
#
1821
# Returns a Hyperclient::EntryPoint
1922
def self.new(url, &block)
20-
Hyperclient::EntryPoint.new(url, &block)
23+
URL_TO_ENDPOINT_MAPPING[url] = Hyperclient::EntryPoint.new(url, &block)
24+
end
25+
26+
def self.lookup_entry_point(uri)
27+
URL_TO_ENDPOINT_MAPPING[uri] || raise(ArgumentError, "Entry point not registered for #{uri}")
2128
end
2229
end

lib/hyperclient/global_id.rb

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# frozen_string_literal: true
2+
3+
require 'delegate'
4+
require 'globalid'
5+
6+
module Hyperclient
7+
module GlobalId
8+
class Locator
9+
def locate(gid)
10+
Hyperclient
11+
.lookup_entry_point(gid.params['endpoint'])
12+
.public_send(gid.params['key'], gid.params.except('endpoint', 'key'))
13+
end
14+
end
15+
16+
class Serializable < SimpleDelegator
17+
def id
18+
_url
19+
end
20+
end
21+
22+
private_constant :Serializable
23+
24+
def self.app_name
25+
"#{GlobalID.app}-hyperclient"
26+
end
27+
28+
def self.setup!
29+
::Hyperclient::Link.include ::GlobalID::Identification
30+
::Hyperclient::Link.prepend ::Hyperclient::GlobalId
31+
32+
::GlobalID::Locator.use app_name, ::Hyperclient::GlobalId::Locator.new
33+
end
34+
35+
def to_global_id(options = {})
36+
GlobalID.create(Serializable.new(self), default_global_id_options.merge(options))
37+
end
38+
alias to_gid to_global_id
39+
40+
def to_signed_global_id(options = {})
41+
SignedGlobalID.create(Serializable.new(self), default_global_id_options.merge(options))
42+
end
43+
alias to_sgid to_signed_global_id
44+
45+
private
46+
47+
def default_global_id_options
48+
{
49+
app: ::Hyperclient::GlobalId.app_name,
50+
endpoint: @entry_point._url,
51+
key: @key,
52+
**@uri_variables || {},
53+
}
54+
end
55+
end
56+
end

lib/hyperclient/railtie.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module Hyperclient
2+
class Railtie < ::Rails::Railtie #:nodoc:
3+
initializer 'hyperclient.client.attach_log_subscriber' do
4+
ActiveSupport.on_load(:active_job) do
5+
require 'hyperclient/global_id'
6+
7+
::Hyperclient::GlobalId.setup!
8+
end
9+
end
10+
end
11+
end

test/hyperclient/link_test.rb

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require_relative '../test_helper'
22
require 'hyperclient'
3+
require 'hyperclient/global_id'
34

45
module Hyperclient
56
describe Link do
@@ -350,5 +351,33 @@ module Hyperclient
350351
end
351352
end
352353
end
354+
355+
describe 'GlobalId Support' do
356+
describe '#to_global_id' do
357+
before do
358+
Hyperclient::GlobalId.setup!
359+
Hyperclient::URL_TO_ENDPOINT_MAPPING[entry_point._url] = entry_point
360+
end
361+
362+
it "serializes the object with entry point, key and uri_variables if present" do
363+
link = Link.new('key', { 'href' => "http://api.example.org/key" }, entry_point)
364+
365+
stub_request(entry_point.connection) do |stub|
366+
stub.get('http://api.example.org/') { [200, {}, { '_links' => { 'key' => { 'href' => 'http://api.example.org/key' } } }] }
367+
end
368+
369+
actual = GlobalID.find(link.to_global_id)
370+
371+
actual._url.must_equal(link._url)
372+
end
373+
374+
it "raises an exception when the hypermedia URL is missing" do
375+
link_without_href = Link.new('key', { }, entry_point)
376+
message = "Unable to create a Global ID for Hyperclient::GlobalId::Serializable without a model id."
377+
378+
-> { link_without_href.to_global_id }.must_raise(URI::GID::MissingModelIdError, message)
379+
end
380+
end
381+
end
353382
end
354-
end
383+
end

0 commit comments

Comments
 (0)