jsonapi-renderer 0.1.3 → 0.2.0
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccb0dad8d132bc0c9faa63ed697f2b081b8d734e
|
4
|
+
data.tar.gz: 55d657476428b0d6c484963fb01ea24f628d826e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8a4a13a02cd3214d4fe6605af7d6d96cc5218d2a566f541a702477030d94c9d5b402e177b6cbce40ed420e705bffb317c1c4f05d3a7cac9622972a667b57c03
|
7
|
+
data.tar.gz: d8666ed16a3e328e6eed21ac79585e72319fca38a149d06f1ce17bee706259aa227bc875dcf7c7463aee678434aac6884f5d87fe1869e0cc75932bd75a658467
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ class ResourceInterface
|
|
48
48
|
# @return [String]
|
49
49
|
def jsonapi_id; end
|
50
50
|
|
51
|
-
# Returns a hash containing, for each included relationship, an array of the
|
51
|
+
# Returns a hash containing, for each included relationship, an array of the
|
52
52
|
# resources to be included from that one.
|
53
53
|
# @param included_relationships [Array<Symbol>] The keys of the relationships
|
54
54
|
# to be included.
|
@@ -57,8 +57,8 @@ class ResourceInterface
|
|
57
57
|
|
58
58
|
# Returns a JSON API-compliant representation of the resource as a hash.
|
59
59
|
# @param options [Hash]
|
60
|
-
# @option fields [
|
61
|
-
# @option include [
|
60
|
+
# @option fields [Set<Symbol>, Nil] The requested fields, or nil.
|
61
|
+
# @option include [Set<Symbol>] The requested relationships to
|
62
62
|
# include (defaults to []).
|
63
63
|
# @return [Hash]
|
64
64
|
def as_jsonapi(options = {}); end
|
@@ -87,6 +87,18 @@ JSONAPI.render(data: resources,
|
|
87
87
|
|
88
88
|
This returns a JSON API compliant hash representing the described document.
|
89
89
|
|
90
|
+
#### Rendering a relationship
|
91
|
+
```ruby
|
92
|
+
JSONAPI.render(data: resource,
|
93
|
+
relationship: :posts,
|
94
|
+
include: include_string,
|
95
|
+
fields: fields_hash,
|
96
|
+
meta: meta_hash,
|
97
|
+
links: links_hash)
|
98
|
+
```
|
99
|
+
|
100
|
+
This returns a JSON API compliant hash representing the described document.
|
101
|
+
|
90
102
|
### Rendering errors
|
91
103
|
|
92
104
|
```ruby
|
@@ -100,6 +112,32 @@ returns a JSON API-compliant representation of the error.
|
|
100
112
|
|
101
113
|
This returns a JSON API compliant hash representing the described document.
|
102
114
|
|
115
|
+
### Caching
|
116
|
+
|
117
|
+
The generated JSON fragments can be cached in any cache implementation
|
118
|
+
supporting the `fetch_multi` method.
|
119
|
+
|
120
|
+
When using caching, the serializable resources must implement an
|
121
|
+
additional `jsonapi_cache_key` method:
|
122
|
+
```ruby
|
123
|
+
# Returns a cache key for the resource, parametered by the `include` and
|
124
|
+
# `fields` options.
|
125
|
+
# @param options [Hash]
|
126
|
+
# @option fields [Set<Symbol>, Nil] The requested fields, or nil.
|
127
|
+
# @option include [Set<Symbol>] The requested relationships to
|
128
|
+
# include (defaults to []).
|
129
|
+
# @return [String]
|
130
|
+
def jsonapi_cache_key(options = {}); end
|
131
|
+
```
|
132
|
+
|
133
|
+
The cache instance must be passed to the renderer as follows:
|
134
|
+
```ruby
|
135
|
+
JSONAPI.render(data: resources,
|
136
|
+
include: include_string,
|
137
|
+
fields: fields_hash,
|
138
|
+
cache: cache_instance)
|
139
|
+
```
|
140
|
+
|
103
141
|
## License
|
104
142
|
|
105
143
|
jsonapi-renderer is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'jsonapi/renderer/resources_processor'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
class Renderer
|
5
|
+
# @private
|
6
|
+
class CachedResourcesProcessor < ResourcesProcessor
|
7
|
+
class JSONString < String
|
8
|
+
def to_json(*)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(cache)
|
14
|
+
@cache = cache
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_resources
|
18
|
+
[@primary, @included].each do |resources|
|
19
|
+
cache_hash = cache_key_map(resources)
|
20
|
+
processed_resources = @cache.fetch_multi(cache_hash.keys) do |key|
|
21
|
+
res, include, fields = cache_hash[key]
|
22
|
+
json = res.as_jsonapi(include: include, fields: fields).to_json
|
23
|
+
|
24
|
+
JSONString.new(json)
|
25
|
+
end
|
26
|
+
|
27
|
+
resources.replace(processed_resources.values)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def cache_key_map(resources)
|
32
|
+
resources.each_with_object({}) do |res, h|
|
33
|
+
ri = [res.jsonapi_type, res.jsonapi_id]
|
34
|
+
include_dir = @include_rels[ri]
|
35
|
+
fields = @fields[ri.first.to_sym]
|
36
|
+
h[res.jsonapi_cache_key(include: include_dir, fields: fields)] =
|
37
|
+
[res, include_dir, fields]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'jsonapi/include_directive'
|
2
|
-
require 'jsonapi/renderer/
|
2
|
+
require 'jsonapi/renderer/simple_resources_processor'
|
3
|
+
require 'jsonapi/renderer/cached_resources_processor'
|
3
4
|
|
4
5
|
module JSONAPI
|
5
6
|
class Renderer
|
7
|
+
# @private
|
6
8
|
class Document
|
7
9
|
def initialize(params = {})
|
8
10
|
@data = params.fetch(:data, :no_data)
|
@@ -12,6 +14,8 @@ module JSONAPI
|
|
12
14
|
@fields = _symbolize_fields(params[:fields] || {})
|
13
15
|
@jsonapi = params[:jsonapi]
|
14
16
|
@include = JSONAPI::IncludeDirective.new(params[:include] || {})
|
17
|
+
@relationship = params[:relationship]
|
18
|
+
@cache = params[:cache]
|
15
19
|
end
|
16
20
|
|
17
21
|
def to_hash
|
@@ -21,31 +25,69 @@ module JSONAPI
|
|
21
25
|
|
22
26
|
private
|
23
27
|
|
28
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength
|
29
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
24
30
|
def document_hash
|
25
31
|
{}.tap do |hash|
|
26
|
-
if @
|
32
|
+
if @relationship
|
33
|
+
hash.merge!(relationship_hash)
|
34
|
+
elsif @data != :no_data
|
27
35
|
hash.merge!(data_hash)
|
28
36
|
elsif @errors.any?
|
29
37
|
hash.merge!(errors_hash)
|
30
38
|
end
|
31
|
-
hash[:links] = @links
|
32
|
-
hash[:meta] = @meta
|
33
|
-
hash[:jsonapi] = @jsonapi
|
39
|
+
hash[:links] = @links if @links.any?
|
40
|
+
hash[:meta] = @meta unless @meta.nil?
|
41
|
+
hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
|
34
42
|
end
|
35
43
|
end
|
44
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/MethodLength
|
45
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
36
46
|
|
37
47
|
def data_hash
|
38
48
|
primary, included =
|
39
|
-
|
49
|
+
resources_processor.process(Array(@data), @include, @fields)
|
40
50
|
{}.tap do |hash|
|
41
51
|
hash[:data] = @data.respond_to?(:to_ary) ? primary : primary[0]
|
42
52
|
hash[:included] = included if included.any?
|
43
53
|
end
|
44
54
|
end
|
45
55
|
|
56
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
57
|
+
def relationship_hash
|
58
|
+
rel_name = @relationship.to_sym
|
59
|
+
data = @data.jsonapi_related([rel_name])[rel_name]
|
60
|
+
included =
|
61
|
+
if @include.key?(rel_name)
|
62
|
+
resources_processor.process(data, @include[rel_name], @fields)
|
63
|
+
.flatten!
|
64
|
+
else
|
65
|
+
[]
|
66
|
+
end
|
67
|
+
|
68
|
+
res = @data.as_jsonapi(fields: [rel_name], include: [rel_name])
|
69
|
+
rel = res[:relationships][rel_name]
|
70
|
+
@links = rel[:links].merge!(@links)
|
71
|
+
@meta ||= rel[:meta]
|
72
|
+
|
73
|
+
{}.tap do |hash|
|
74
|
+
hash[:data] = rel[:data]
|
75
|
+
hash[:included] = included if included.any?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
79
|
+
|
46
80
|
def errors_hash
|
47
81
|
{}.tap do |hash|
|
48
|
-
hash[:errors] = @errors.
|
82
|
+
hash[:errors] = @errors.flat_map(&:as_jsonapi)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def resources_processor
|
87
|
+
if @cache
|
88
|
+
CachedResourcesProcessor.new(@cache)
|
89
|
+
else
|
90
|
+
SimpleResourcesProcessor.new
|
49
91
|
end
|
50
92
|
end
|
51
93
|
|
@@ -2,14 +2,13 @@ require 'set'
|
|
2
2
|
|
3
3
|
module JSONAPI
|
4
4
|
class Renderer
|
5
|
+
# @private
|
5
6
|
class ResourcesProcessor
|
6
|
-
def
|
7
|
+
def process(resources, include, fields)
|
7
8
|
@resources = resources
|
8
9
|
@include = include
|
9
10
|
@fields = fields
|
10
|
-
end
|
11
11
|
|
12
|
-
def process
|
13
12
|
traverse_resources
|
14
13
|
process_resources
|
15
14
|
|
@@ -73,14 +72,7 @@ module JSONAPI
|
|
73
72
|
end
|
74
73
|
|
75
74
|
def process_resources
|
76
|
-
|
77
|
-
resources.map! do |res|
|
78
|
-
ri = [res.jsonapi_type, res.jsonapi_id]
|
79
|
-
include_dir = @include_rels[ri]
|
80
|
-
fields = @fields[res.jsonapi_type.to_sym]
|
81
|
-
res.as_jsonapi(include: include_dir, fields: fields)
|
82
|
-
end
|
83
|
-
end
|
75
|
+
raise 'Not implemented'
|
84
76
|
end
|
85
77
|
end
|
86
78
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'jsonapi/renderer/resources_processor'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
class Renderer
|
5
|
+
# @api private
|
6
|
+
class SimpleResourcesProcessor < ResourcesProcessor
|
7
|
+
def process_resources
|
8
|
+
[@primary, @included].each do |resources|
|
9
|
+
resources.map! do |res|
|
10
|
+
ri = [res.jsonapi_type, res.jsonapi_id]
|
11
|
+
include_dir = @include_rels[ri]
|
12
|
+
fields = @fields[res.jsonapi_type.to_sym]
|
13
|
+
res.as_jsonapi(include: include_dir, fields: fields)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-renderer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: simplecov
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
54
|
+
version: '0'
|
55
55
|
description: Efficiently render JSON API documents.
|
56
56
|
email: lucas.hosseini@gmail.com
|
57
57
|
executables: []
|
@@ -62,8 +62,10 @@ files:
|
|
62
62
|
- lib/jsonapi/include_directive.rb
|
63
63
|
- lib/jsonapi/include_directive/parser.rb
|
64
64
|
- lib/jsonapi/renderer.rb
|
65
|
+
- lib/jsonapi/renderer/cached_resources_processor.rb
|
65
66
|
- lib/jsonapi/renderer/document.rb
|
66
67
|
- lib/jsonapi/renderer/resources_processor.rb
|
68
|
+
- lib/jsonapi/renderer/simple_resources_processor.rb
|
67
69
|
homepage: https://github.com/jsonapi-rb/jsonapi-renderer
|
68
70
|
licenses:
|
69
71
|
- MIT
|
@@ -84,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
86
|
version: '0'
|
85
87
|
requirements: []
|
86
88
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.6.
|
89
|
+
rubygems_version: 2.6.13
|
88
90
|
signing_key:
|
89
91
|
specification_version: 4
|
90
92
|
summary: Render JSONAPI documents.
|