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: 64a6b359e09767d1fb82f5c99e5c00493180fee2
4
- data.tar.gz: 7cbe497431c5af06536206776c5ea4c791085e3c
3
+ metadata.gz: ccb0dad8d132bc0c9faa63ed697f2b081b8d734e
4
+ data.tar.gz: 55d657476428b0d6c484963fb01ea24f628d826e
5
5
  SHA512:
6
- metadata.gz: 560dd5946e8a744de498eabc762f1f90f4c834a215a2b57e58adba24b9b5f6d6e1e5b878123195b82c2ec6f58f64468cdb530159cd30e5bb99f226134238d66a
7
- data.tar.gz: 4fdf98ad9829edfc5e254b4df9a7a7f765ee9de05784c76c6f6e35ee73f64b154e75bf40af6953873f0d1cfdeb0dbb096401cc982eac546388930b0219a5741b
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 [Array<Symbol>, Nil] The requested fields, or nil.
61
- # @option include [Array<Symbol>] The requested relationships to
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/resources_processor'
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 @data != :no_data
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 if @links.any?
32
- hash[:meta] = @meta unless @meta.nil?
33
- hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
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
- ResourcesProcessor.new(Array(@data), @include, @fields).process
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.map(&:as_jsonapi)
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 initialize(resources, include, fields)
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
- [@primary, @included].each do |resources|
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.1.3
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-07-12 00:00:00.000000000 Z
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: codecov
42
+ name: simplecov
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0.1'
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.1'
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.12
89
+ rubygems_version: 2.6.13
88
90
  signing_key:
89
91
  specification_version: 4
90
92
  summary: Render JSONAPI documents.