simple_jsonapi_client 0.1.0 → 0.2.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 +4 -4
- data/.travis.yml +2 -0
- data/Dockerfile +5 -5
- data/README.md +19 -1
- data/docker-compose.yml +8 -8
- data/lib/simple_jsonapi_client/base.rb +22 -11
- data/lib/simple_jsonapi_client/errors/api_error.rb +1 -0
- data/lib/simple_jsonapi_client/redirection/fetch_all.rb +4 -2
- data/lib/simple_jsonapi_client/utils.rb +47 -0
- data/lib/simple_jsonapi_client/version.rb +1 -1
- data/simple_jsonapi_client.gemspec +3 -4
- metadata +23 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87849cea3879d98446f4b38def54869878ee782a4cd5982eba053ba38df0163e
|
4
|
+
data.tar.gz: 4abec126d2887df66b608c1497d70b5d539b74f4b83b5df3da2973c0012a04e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bbb34268e4fbeecebadca831d8ae1e7cf26e422f729973e837686eb3c1b918b23a1d557fd9f13d4cf2844578193470449aff1c165ad4e183d103d2945205ee7
|
7
|
+
data.tar.gz: 73086d69a203c6f67077540e13c02f549cf74009698991bd2f5c698aa8c5c847df8219f99ce49d917850da9323f0f742b659306984e82b24da8d7f77e98c46cf
|
data/.travis.yml
CHANGED
data/Dockerfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
FROM ruby:2.
|
1
|
+
FROM ruby:2.6.6
|
2
2
|
RUN apt-get update -qq
|
3
|
-
RUN gem update
|
3
|
+
RUN gem update --system
|
4
|
+
RUN gem install -v 2.2.3 bundler -N
|
5
|
+
ENV BUNDLER_VERSION=2.2
|
4
6
|
RUN mkdir /simple_jsonapi_client
|
5
7
|
WORKDIR /simple_jsonapi_client
|
6
|
-
ADD
|
7
|
-
ADD simple_jsonapi_client.gemspec /simple_jsonapi_client/simple_jsonapi_client.gemspec
|
8
|
-
ADD . /simple_jsonapi_client
|
8
|
+
ADD . .
|
9
9
|
RUN bundle install
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
[](https://travis-ci.org/amcaplan/simple_jsonapi_client)
|
2
|
+
[](https://badge.fury.io/rb/simple_jsonapi_client)
|
2
3
|
|
3
4
|
# What is `SimpleJSONAPIClient`?
|
4
5
|
|
@@ -165,11 +166,28 @@ post.comments.first.author # will not make another web request
|
|
165
166
|
|
166
167
|
`SimpleJSONAPIClient` will check the included records for related records you access through the returned model.
|
167
168
|
|
168
|
-
And finally, you can use JSONAPI-style filtering as well:
|
169
|
+
And finally, you can use JSONAPI-style filtering and pagination as well:
|
169
170
|
|
170
171
|
```ruby
|
172
|
+
# Given 3 authors...
|
173
|
+
JSONAPIAppClient::Author.fetch_all(connection: connection).to_a
|
174
|
+
=> [#<JSONAPIAppClient::Author id=1 name="Filbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/1/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/1/comments>>,
|
175
|
+
#<JSONAPIAppClient::Author id=2 name="Dilbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/2/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/2/comments>>,
|
176
|
+
#<JSONAPIAppClient::Author id=3 name="Wilbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/3/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/3/comments>>]
|
177
|
+
|
178
|
+
# Filtering by name
|
171
179
|
JSONAPIAppClient::Author.fetch_all(connection: connection, filter_opts: { name: 'Filbert' }).to_a
|
172
180
|
=> [#<JSONAPIAppClient::Author id=1 name="Filbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/1/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/1/comments>>]
|
181
|
+
|
182
|
+
# Just grabbing the last page
|
183
|
+
JSONAPIAppClient::Author.fetch_all(connection: connection, page_opts: { size: 1, number: 3 }).to_a
|
184
|
+
=> [#<JSONAPIAppClient::Author id=3 name="Wilbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/3/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/3/comments>>]
|
185
|
+
|
186
|
+
# You can adjust the pagination strategy and SimpleJSONAPIClient will follow it, but return the same results
|
187
|
+
JSONAPIAppClient::Author.fetch_all(connection: connection, page_opts: { size: 1, number: 1 }).to_a
|
188
|
+
=> [#<JSONAPIAppClient::Author id=1 name="Filbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/1/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/1/comments>>,
|
189
|
+
#<JSONAPIAppClient::Author id=2 name="Dilbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/2/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/2/comments>>,
|
190
|
+
#<JSONAPIAppClient::Author id=3 name="Wilbert" posts=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Post url=http://jsonapi_app_console:3002/authors/3/posts> comments=#<SimpleJSONAPIClient::Relationships::ArrayLinkRelationship model_class=JSONAPIAppClient::Comment url=http://jsonapi_app_console:3002/authors/3/comments>>]
|
173
191
|
```
|
174
192
|
|
175
193
|
## Creating
|
data/docker-compose.yml
CHANGED
@@ -2,6 +2,8 @@ version: '3'
|
|
2
2
|
services:
|
3
3
|
db:
|
4
4
|
image: postgres
|
5
|
+
ports:
|
6
|
+
- "5432:5432"
|
5
7
|
spec:
|
6
8
|
build: .
|
7
9
|
entrypoint: bin/wait_for_it jsonapi_app_spec:3001 -t 30 --
|
@@ -15,10 +17,9 @@ services:
|
|
15
17
|
API_PORT: 3001
|
16
18
|
jsonapi_app_spec:
|
17
19
|
build: ./spec/jsonapi_app
|
18
|
-
entrypoint: bin/wait_for_it db:5432 -t
|
19
|
-
volumes:
|
20
|
-
- ./spec/jsonapi_app:/jsonapi_app
|
21
|
-
- /jsonapi_app/tmp/
|
20
|
+
entrypoint: bin/wait_for_it db:5432 -t 60 --
|
21
|
+
# volumes:
|
22
|
+
# - ./spec/jsonapi_app:/jsonapi_app
|
22
23
|
command: bundle exec rails s -p 3001 -b '0.0.0.0'
|
23
24
|
ports:
|
24
25
|
- "3001:3001"
|
@@ -39,10 +40,9 @@ services:
|
|
39
40
|
API_PORT: 3002
|
40
41
|
jsonapi_app_console:
|
41
42
|
build: ./spec/jsonapi_app
|
42
|
-
entrypoint: bin/wait_for_it db:5432 -t
|
43
|
-
volumes:
|
44
|
-
- ./spec/jsonapi_app:/jsonapi_app
|
45
|
-
- /jsonapi_app/tmp/
|
43
|
+
entrypoint: bin/wait_for_it db:5432 -t 60 --
|
44
|
+
# volumes:
|
45
|
+
# - ./spec/jsonapi_app:/jsonapi_app
|
46
46
|
command: bundle exec rails s -p 3002 -b '0.0.0.0'
|
47
47
|
ports:
|
48
48
|
- "3002:3002"
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'active_support/core_ext/hash/transform_values'
|
1
|
+
require 'simple_jsonapi_client/utils'
|
3
2
|
require 'simple_jsonapi_client/error'
|
4
3
|
require 'simple_jsonapi_client/relationships/relationship'
|
5
4
|
require 'simple_jsonapi_client/redirection/fetch_all'
|
@@ -163,10 +162,12 @@ module SimpleJSONAPIClient
|
|
163
162
|
url_opts: {},
|
164
163
|
url: self::COLLECTION_URL % url_opts,
|
165
164
|
filter_opts: {},
|
165
|
+
page_opts: {},
|
166
166
|
includes: [])
|
167
167
|
params = {}
|
168
168
|
params[:include] = includes.join(',') unless includes.empty?
|
169
169
|
params[:filter] = filter_opts unless filter_opts.empty?
|
170
|
+
params[:page] = page_opts unless page_opts.empty?
|
170
171
|
connection.get(url, params)
|
171
172
|
end
|
172
173
|
|
@@ -206,12 +207,22 @@ module SimpleJSONAPIClient
|
|
206
207
|
def interpret_empty_response(response, connection)
|
207
208
|
end
|
208
209
|
|
209
|
-
|
210
|
-
relationships
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
210
|
+
if {}.respond_to?(:transform_values)
|
211
|
+
def interpreted_relationships(relationships)
|
212
|
+
relationships.transform_values { |value|
|
213
|
+
if (relationship = relationship_from(value))
|
214
|
+
{ data: relationship }
|
215
|
+
end
|
216
|
+
}
|
217
|
+
end
|
218
|
+
else
|
219
|
+
def interpreted_relationships(relationships)
|
220
|
+
Utils.transform_values(relationships) { |value|
|
221
|
+
if (relationship = relationship_from(value))
|
222
|
+
{ data: relationship }
|
223
|
+
end
|
224
|
+
}
|
225
|
+
end
|
215
226
|
end
|
216
227
|
|
217
228
|
def relationship_from(value)
|
@@ -236,12 +247,12 @@ module SimpleJSONAPIClient
|
|
236
247
|
attr_reader :id, :context
|
237
248
|
|
238
249
|
def initialize(meta: nil, id:, attributes: nil, relationships: nil, included: {}, connection:, context: nil)
|
239
|
-
@meta =
|
250
|
+
@meta = Utils.symbolize_keys(meta) if meta
|
240
251
|
@id = id
|
241
252
|
@included = included
|
242
253
|
@connection = connection
|
243
254
|
@context = context
|
244
|
-
@attributes =
|
255
|
+
@attributes = Utils.symbolize_keys(attributes) if attributes
|
245
256
|
@input_relationships = relationships
|
246
257
|
end
|
247
258
|
|
@@ -265,7 +276,7 @@ module SimpleJSONAPIClient
|
|
265
276
|
@relationships ||=
|
266
277
|
begin
|
267
278
|
if input_relationships
|
268
|
-
relationships_to_models(
|
279
|
+
relationships_to_models(Utils.symbolize_keys(input_relationships))
|
269
280
|
else
|
270
281
|
loaded_record.relationships
|
271
282
|
end
|
@@ -3,8 +3,9 @@ require 'simple_jsonapi_client/redirection/proxy'
|
|
3
3
|
module SimpleJSONAPIClient
|
4
4
|
module Redirection
|
5
5
|
class FetchAll < ::SimpleJSONAPIClient::Redirection::Proxy
|
6
|
-
def_delegators :internal_object, *(Array.instance_methods(false) - instance_methods)
|
7
6
|
def_delegators :internal_enumerator, *(Enumerator.instance_methods(false) - instance_methods)
|
7
|
+
def_delegators :internal_enumerator, *(Enumerable.instance_methods(false) - instance_methods)
|
8
|
+
def_delegators :internal_object, :size, *(Array.instance_methods(false) - instance_methods)
|
8
9
|
|
9
10
|
def initialize(base_opts, &operation)
|
10
11
|
@base_opts = base_opts
|
@@ -29,8 +30,9 @@ module SimpleJSONAPIClient
|
|
29
30
|
current_response['data'].each do |record|
|
30
31
|
yielder << record
|
31
32
|
end
|
32
|
-
break unless (next_link =
|
33
|
+
break unless (next_link = Utils.hash_dig(current_response, 'links', 'next'))
|
33
34
|
current_opts.merge!(url_opts: {}, url: next_link)
|
35
|
+
current_opts.delete(:page_opts)
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SimpleJSONAPIClient
|
2
|
+
module Utils
|
3
|
+
class << self
|
4
|
+
# Implementation adapted from ActiveSupport
|
5
|
+
# Copyright (c) 2005-2019 David Heinemeier Hansson
|
6
|
+
# https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activesupport/lib/active_support/core_ext/hash/keys.rb
|
7
|
+
def symbolize_keys(hash)
|
8
|
+
result = {}
|
9
|
+
hash.each_key do |key|
|
10
|
+
result[(key.to_sym rescue key)] = hash[key]
|
11
|
+
end
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash_dig(hash, *keys)
|
16
|
+
if hash.respond_to?(:dig)
|
17
|
+
hash.dig(*keys)
|
18
|
+
else
|
19
|
+
dig(hash, keys)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Implementation adapted from the hash_dig gem, Copyright (c) 2015 Colin Kelley, MIT License
|
26
|
+
# https://github.com/Invoca/ruby_dig/blob/19fa8c1d2cc7706d015a3004f028169a2ff83391/lib/ruby_dig.rb
|
27
|
+
def dig(hash, key, *rest)
|
28
|
+
value = hash[key]
|
29
|
+
if value.nil? || rest.empty?
|
30
|
+
value
|
31
|
+
elsif value.is_a?(Hash) || value.is_a?(Array)
|
32
|
+
dig(value, *rest)
|
33
|
+
else
|
34
|
+
fail TypeError, "#{value.class} does not work with #dig" # should not happen with our use of #dig
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def transform_values(hash)
|
39
|
+
result = {}
|
40
|
+
hash.each do |key, value|
|
41
|
+
result[key] = yield(value)
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -20,11 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency "faraday", "
|
24
|
-
spec.add_dependency "faraday_middleware", "
|
25
|
-
spec.add_dependency "activesupport", ">= 3.1.12", "< 6"
|
23
|
+
spec.add_dependency "faraday", ">= 0.12", "< 2.0"
|
24
|
+
spec.add_dependency "faraday_middleware", "> 0.11", "< 2.0"
|
26
25
|
|
27
|
-
spec.add_development_dependency "bundler", "~>
|
26
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
28
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
29
28
|
spec.add_development_dependency "rspec", "~> 3.0"
|
30
29
|
spec.add_development_dependency "pry", "~> 0"
|
metadata
CHANGED
@@ -1,77 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_jsonapi_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ariel Caplan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.12'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '0.12'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: faraday_middleware
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">"
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '0.11'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.11'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activesupport
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 3.1.12
|
48
40
|
- - "<"
|
49
41
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
42
|
+
version: '2.0'
|
51
43
|
type: :runtime
|
52
44
|
prerelease: false
|
53
45
|
version_requirements: !ruby/object:Gem::Requirement
|
54
46
|
requirements:
|
55
|
-
- - "
|
47
|
+
- - ">"
|
56
48
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
49
|
+
version: '0.11'
|
58
50
|
- - "<"
|
59
51
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
52
|
+
version: '2.0'
|
61
53
|
- !ruby/object:Gem::Dependency
|
62
54
|
name: bundler
|
63
55
|
requirement: !ruby/object:Gem::Requirement
|
64
56
|
requirements:
|
65
57
|
- - "~>"
|
66
58
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
59
|
+
version: '2.2'
|
68
60
|
type: :development
|
69
61
|
prerelease: false
|
70
62
|
version_requirements: !ruby/object:Gem::Requirement
|
71
63
|
requirements:
|
72
64
|
- - "~>"
|
73
65
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
66
|
+
version: '2.2'
|
75
67
|
- !ruby/object:Gem::Dependency
|
76
68
|
name: rake
|
77
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +106,7 @@ dependencies:
|
|
114
106
|
- - "~>"
|
115
107
|
- !ruby/object:Gem::Version
|
116
108
|
version: '0'
|
117
|
-
description:
|
109
|
+
description:
|
118
110
|
email:
|
119
111
|
- arielmcaplan@gmail.com
|
120
112
|
executables: []
|
@@ -151,13 +143,14 @@ files:
|
|
151
143
|
- lib/simple_jsonapi_client/relationships/relationship.rb
|
152
144
|
- lib/simple_jsonapi_client/relationships/singular_data_relationship.rb
|
153
145
|
- lib/simple_jsonapi_client/relationships/singular_link_relationship.rb
|
146
|
+
- lib/simple_jsonapi_client/utils.rb
|
154
147
|
- lib/simple_jsonapi_client/version.rb
|
155
148
|
- simple_jsonapi_client.gemspec
|
156
149
|
homepage: https://github.com/amcaplan/simple_jsonapi_client
|
157
150
|
licenses:
|
158
151
|
- MIT
|
159
152
|
metadata: {}
|
160
|
-
post_install_message:
|
153
|
+
post_install_message:
|
161
154
|
rdoc_options: []
|
162
155
|
require_paths:
|
163
156
|
- lib
|
@@ -172,9 +165,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
165
|
- !ruby/object:Gem::Version
|
173
166
|
version: '0'
|
174
167
|
requirements: []
|
175
|
-
|
176
|
-
|
177
|
-
signing_key:
|
168
|
+
rubygems_version: 3.2.3
|
169
|
+
signing_key:
|
178
170
|
specification_version: 4
|
179
171
|
summary: Framework for writing clients for JSONAPI APIs in Ruby.
|
180
172
|
test_files: []
|