New Upstream Release - ruby-jsonapi-renderer
Ready changes
Summary
Merged new upstream version: 0.2.2 (was: 0.1.3).
Resulting package
Built on 2022-06-01T10:13 (took 3m13s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases ruby-jsonapi-renderer
Lintian Result
Diff
diff --git a/README.md b/README.md
index 7d8bf4d..2b6d443 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ class ResourceInterface
# @return [String]
def jsonapi_id; end
- # Returns a hash containing, for each included relationship, an array of the
+ # Returns a hash containing, for each included relationship, an array of the
# resources to be included from that one.
# @param included_relationships [Array<Symbol>] The keys of the relationships
# to be included.
@@ -57,8 +57,8 @@ class ResourceInterface
# Returns a JSON API-compliant representation of the resource as a hash.
# @param options [Hash]
- # @option fields [Array<Symbol>, Nil] The requested fields, or nil.
- # @option include [Array<Symbol>] The requested relationships to
+ # @option fields [Set<Symbol>, Nil] The requested fields, or nil.
+ # @option include [Set<Symbol>] The requested relationships to
# include (defaults to []).
# @return [Hash]
def as_jsonapi(options = {}); end
@@ -87,6 +87,18 @@ JSONAPI.render(data: resources,
This returns a JSON API compliant hash representing the described document.
+#### Rendering a relationship
+```ruby
+JSONAPI.render(data: resource,
+ relationship: :posts,
+ include: include_string,
+ fields: fields_hash,
+ meta: meta_hash,
+ links: links_hash)
+```
+
+This returns a JSON API compliant hash representing the described document.
+
### Rendering errors
```ruby
@@ -100,6 +112,32 @@ returns a JSON API-compliant representation of the error.
This returns a JSON API compliant hash representing the described document.
+### Caching
+
+The generated JSON fragments can be cached in any cache implementation
+supporting the `fetch_multi` method.
+
+When using caching, the serializable resources must implement an
+additional `jsonapi_cache_key` method:
+```ruby
+ # Returns a cache key for the resource, parameterized by the `include` and
+ # `fields` options.
+ # @param options [Hash]
+ # @option fields [Set<Symbol>, Nil] The requested fields, or nil.
+ # @option include [Set<Symbol>] The requested relationships to
+ # include (defaults to []).
+ # @return [String]
+ def jsonapi_cache_key(options = {}); end
+```
+
+The cache instance must be passed to the renderer as follows:
+```ruby
+JSONAPI.render(data: resources,
+ include: include_string,
+ fields: fields_hash,
+ cache: cache_instance)
+```
+
## License
jsonapi-renderer is released under the [MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/debian/changelog b/debian/changelog
index 9005761..c02ed5d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ruby-jsonapi-renderer (0.1.3-2) UNRELEASED; urgency=medium
+ruby-jsonapi-renderer (0.2.2-1) UNRELEASED; urgency=medium
[ Utkarsh Gupta ]
* Add salsa-ci.yml
@@ -17,8 +17,9 @@ ruby-jsonapi-renderer (0.1.3-2) UNRELEASED; urgency=medium
+ ruby-jsonapi-renderer: Add :all qualifier for ruby dependency.
* Update watch file format version to 4.
* Bump debhelper from old 12 to 13.
+ * New upstream release.
- -- Utkarsh Gupta <guptautkarsh2102@gmail.com> Tue, 13 Aug 2019 05:50:36 +0530
+ -- Utkarsh Gupta <guptautkarsh2102@gmail.com> Wed, 01 Jun 2022 10:10:12 -0000
ruby-jsonapi-renderer (0.1.3-1) unstable; urgency=medium
diff --git a/jsonapi-renderer.gemspec b/jsonapi-renderer.gemspec
index fa1c608..eccdd6f 100644
--- a/jsonapi-renderer.gemspec
+++ b/jsonapi-renderer.gemspec
@@ -2,39 +2,39 @@
# This file has been automatically generated by gem2tgz #
#########################################################
# -*- encoding: utf-8 -*-
-# stub: jsonapi-renderer 0.1.3 ruby lib
+# stub: jsonapi-renderer 0.2.2 ruby lib
Gem::Specification.new do |s|
s.name = "jsonapi-renderer".freeze
- s.version = "0.1.3"
+ s.version = "0.2.2"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Lucas Hosseini".freeze]
- s.date = "2017-07-12"
+ s.date = "2019-06-13"
s.description = "Efficiently render JSON API documents.".freeze
s.email = "lucas.hosseini@gmail.com".freeze
- s.files = ["README.md".freeze, "lib/jsonapi/include_directive.rb".freeze, "lib/jsonapi/include_directive/parser.rb".freeze, "lib/jsonapi/renderer.rb".freeze, "lib/jsonapi/renderer/document.rb".freeze, "lib/jsonapi/renderer/resources_processor.rb".freeze]
+ s.files = ["README.md".freeze, "lib/jsonapi/include_directive.rb".freeze, "lib/jsonapi/include_directive/parser.rb".freeze, "lib/jsonapi/renderer.rb".freeze, "lib/jsonapi/renderer/cached_resources_processor.rb".freeze, "lib/jsonapi/renderer/document.rb".freeze, "lib/jsonapi/renderer/resources_processor.rb".freeze, "lib/jsonapi/renderer/simple_resources_processor.rb".freeze]
s.homepage = "https://github.com/jsonapi-rb/jsonapi-renderer".freeze
s.licenses = ["MIT".freeze]
- s.rubygems_version = "2.5.2".freeze
+ s.rubygems_version = "2.5.2.1".freeze
s.summary = "Render JSONAPI documents.".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_development_dependency(%q<codecov>.freeze, ["~> 0.1"])
s.add_development_dependency(%q<rake>.freeze, ["~> 11.3"])
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5"])
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
else
- s.add_dependency(%q<codecov>.freeze, ["~> 0.1"])
s.add_dependency(%q<rake>.freeze, ["~> 11.3"])
s.add_dependency(%q<rspec>.freeze, ["~> 3.5"])
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
end
else
- s.add_dependency(%q<codecov>.freeze, ["~> 0.1"])
s.add_dependency(%q<rake>.freeze, ["~> 11.3"])
s.add_dependency(%q<rspec>.freeze, ["~> 3.5"])
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
end
end
diff --git a/lib/jsonapi/include_directive.rb b/lib/jsonapi/include_directive.rb
index 32ec4f7..142633d 100644
--- a/lib/jsonapi/include_directive.rb
+++ b/lib/jsonapi/include_directive.rb
@@ -16,6 +16,8 @@ module JSONAPI
def initialize(include_args, options = {})
include_hash = Parser.parse_include_args(include_args)
@hash = include_hash.each_with_object({}) do |(key, value), hash|
+ raise InvalidKey, key unless valid?(key)
+
hash[key] = self.class.new(value, options)
end
@options = options
@@ -68,5 +70,18 @@ module JSONAPI
string_array.join(',')
end
+
+ class InvalidKey < StandardError; end
+
+ private
+
+ def valid?(key)
+ key.match(valid_json_key_name_regex)
+ end
+
+ def valid_json_key_name_regex
+ # https://jsonapi.org/format/#document-member-names
+ /^(?![\s\-_])[\u0080-\u10FFA-Za-z0-9* _-]+(?<![\s\-_])$/
+ end
end
end
diff --git a/lib/jsonapi/renderer/cached_resources_processor.rb b/lib/jsonapi/renderer/cached_resources_processor.rb
new file mode 100644
index 0000000..1518efc
--- /dev/null
+++ b/lib/jsonapi/renderer/cached_resources_processor.rb
@@ -0,0 +1,47 @@
+require 'jsonapi/renderer/resources_processor'
+
+module JSONAPI
+ class Renderer
+ # @private
+ class CachedResourcesProcessor < ResourcesProcessor
+ class JSONString < String
+ def to_json(*)
+ self
+ end
+ end
+
+ def initialize(cache)
+ @cache = cache
+ end
+
+ def process_resources
+ # NOTE(beauby): This is necessary for cache keys consistency.
+ @include_rels = @include_rels.each_with_object({}) do |(k, v), h|
+ h[k] = v.to_a.sort!
+ end
+
+ [@primary, @included].each do |resources|
+ cache_hash = cache_key_map(resources)
+ processed_resources = @cache.fetch_multi(*cache_hash.keys) do |key|
+ res, include, fields = cache_hash[key]
+ json = res.as_jsonapi(include: include, fields: fields).to_json
+
+ JSONString.new(json)
+ end
+
+ resources.replace(processed_resources.values)
+ end
+ end
+
+ def cache_key_map(resources)
+ resources.each_with_object({}) do |res, h|
+ ri = [res.jsonapi_type, res.jsonapi_id]
+ include_dir = @include_rels[ri]
+ fields = @fields[ri.first.to_sym]
+ h[res.jsonapi_cache_key(include: include_dir, fields: fields)] =
+ [res, include_dir, fields]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jsonapi/renderer/document.rb b/lib/jsonapi/renderer/document.rb
index 6b9d4ad..21a5ae7 100644
--- a/lib/jsonapi/renderer/document.rb
+++ b/lib/jsonapi/renderer/document.rb
@@ -1,17 +1,21 @@
require 'jsonapi/include_directive'
-require 'jsonapi/renderer/resources_processor'
+require 'jsonapi/renderer/simple_resources_processor'
+require 'jsonapi/renderer/cached_resources_processor'
module JSONAPI
class Renderer
+ # @private
class Document
def initialize(params = {})
@data = params.fetch(:data, :no_data)
@errors = params.fetch(:errors, [])
@meta = params[:meta]
@links = params[:links] || {}
- @fields = _symbolize_fields(params[:fields] || {})
+ @fields = _canonize_fields(params[:fields] || {})
@jsonapi = params[:jsonapi]
@include = JSONAPI::IncludeDirective.new(params[:include] || {})
+ @relationship = params[:relationship]
+ @cache = params[:cache]
end
def to_hash
@@ -21,37 +25,75 @@ module JSONAPI
private
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength
+ # rubocop:disable Metrics/CyclomaticComplexity
def document_hash
{}.tap do |hash|
- if @data != :no_data
+ if @relationship
+ hash.merge!(relationship_hash)
+ elsif @data != :no_data
hash.merge!(data_hash)
elsif @errors.any?
hash.merge!(errors_hash)
end
- hash[:links] = @links if @links.any?
- hash[:meta] = @meta unless @meta.nil?
- hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
+ hash[:links] = @links if @links.any?
+ hash[:meta] = @meta unless @meta.nil?
+ hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
end
end
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/MethodLength
+ # rubocop:enable Metrics/CyclomaticComplexity
def data_hash
primary, included =
- ResourcesProcessor.new(Array(@data), @include, @fields).process
+ resources_processor.process(Array(@data), @include, @fields)
{}.tap do |hash|
hash[:data] = @data.respond_to?(:to_ary) ? primary : primary[0]
hash[:included] = included if included.any?
end
end
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
+ def relationship_hash
+ rel_name = @relationship.to_sym
+ data = @data.jsonapi_related([rel_name])[rel_name]
+ included =
+ if @include.key?(rel_name)
+ resources_processor.process(data, @include[rel_name], @fields)
+ .flatten!
+ else
+ []
+ end
+
+ res = @data.as_jsonapi(fields: [rel_name], include: [rel_name])
+ rel = res[:relationships][rel_name]
+ @links = rel[:links].merge!(@links)
+ @meta ||= rel[:meta]
+
+ {}.tap do |hash|
+ hash[:data] = rel[:data]
+ hash[:included] = included if included.any?
+ end
+ end
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
+
def errors_hash
{}.tap do |hash|
- hash[:errors] = @errors.map(&:as_jsonapi)
+ hash[:errors] = @errors.flat_map(&:as_jsonapi)
+ end
+ end
+
+ def resources_processor
+ if @cache
+ CachedResourcesProcessor.new(@cache)
+ else
+ SimpleResourcesProcessor.new
end
end
- def _symbolize_fields(fields)
+ def _canonize_fields(fields)
fields.each_with_object({}) do |(k, v), h|
- h[k.to_sym] = v.map(&:to_sym)
+ h[k.to_sym] = v.map(&:to_sym).sort!
end
end
end
diff --git a/lib/jsonapi/renderer/resources_processor.rb b/lib/jsonapi/renderer/resources_processor.rb
index 9e6be30..dd37110 100644
--- a/lib/jsonapi/renderer/resources_processor.rb
+++ b/lib/jsonapi/renderer/resources_processor.rb
@@ -2,14 +2,13 @@ require 'set'
module JSONAPI
class Renderer
+ # @private
class ResourcesProcessor
- def initialize(resources, include, fields)
+ def process(resources, include, fields)
@resources = resources
@include = include
@fields = fields
- end
- def process
traverse_resources
process_resources
@@ -73,14 +72,7 @@ module JSONAPI
end
def process_resources
- [@primary, @included].each do |resources|
- resources.map! do |res|
- ri = [res.jsonapi_type, res.jsonapi_id]
- include_dir = @include_rels[ri]
- fields = @fields[res.jsonapi_type.to_sym]
- res.as_jsonapi(include: include_dir, fields: fields)
- end
- end
+ raise 'Not implemented'
end
end
end
diff --git a/lib/jsonapi/renderer/simple_resources_processor.rb b/lib/jsonapi/renderer/simple_resources_processor.rb
new file mode 100644
index 0000000..cd2bc0c
--- /dev/null
+++ b/lib/jsonapi/renderer/simple_resources_processor.rb
@@ -0,0 +1,19 @@
+require 'jsonapi/renderer/resources_processor'
+
+module JSONAPI
+ class Renderer
+ # @api private
+ class SimpleResourcesProcessor < ResourcesProcessor
+ def process_resources
+ [@primary, @included].each do |resources|
+ resources.map! do |res|
+ ri = [res.jsonapi_type, res.jsonapi_id]
+ include_dir = @include_rels[ri]
+ fields = @fields[res.jsonapi_type.to_sym]
+ res.as_jsonapi(include: include_dir, fields: fields)
+ end
+ end
+ end
+ end
+ end
+end
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/lib/ruby/vendor_ruby/jsonapi/renderer/cached_resources_processor.rb -rw-r--r-- root/root /usr/lib/ruby/vendor_ruby/jsonapi/renderer/simple_resources_processor.rb -rw-r--r-- root/root /usr/share/doc/ruby-jsonapi-renderer/README.md.gz -rw-r--r-- root/root /usr/share/rubygems-integration/all/specifications/jsonapi-renderer-0.2.2.gemspec
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/share/doc/ruby-jsonapi-renderer/README.md -rw-r--r-- root/root /usr/share/rubygems-integration/all/specifications/jsonapi-renderer-0.1.3.gemspec
No differences were encountered in the control files