jsonapi-renderer 0.1.3 → 0.2.0
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:
|
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.
|