simple_jsonapi_client 0.1.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/amcaplan/simple_jsonapi_client.svg?branch=master)](https://travis-ci.org/amcaplan/simple_jsonapi_client)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/simple_jsonapi_client.svg)](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: []
|