jsonapi-renderer 0.1.1.beta2 → 0.1.1.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/lib/jsonapi/renderer/document.rb +53 -0
- data/lib/jsonapi/renderer/resources_processor.rb +67 -0
- data/lib/jsonapi/renderer.rb +9 -104
- metadata +35 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e0ff29d67fa35e41f7a46f6f4bec480555d9318
|
4
|
+
data.tar.gz: 0d2a619490327182f40f978a917bc80b534f09ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c7b8a58093c1a7a01e1bf352b4232471f483c910386c24d77cc32301bfeb477089a163e78ab57a55d4d3e900a4945ee031cb892fe45e4a0854a3d8fab6d741f
|
7
|
+
data.tar.gz: e61f0a433b6a84b238e9717128073ec934557a9e7ec9e912a29adad883d9c29e902ab65c56862b456407bc617b50239c16a1638ce45f088c63e68bccf83755be
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@ Ruby gem for rendering [JSON API](http://jsonapi.org) documents.
|
|
4
4
|
## Status
|
5
5
|
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/jsonapi-renderer.svg)](https://badge.fury.io/rb/jsonapi-renderer)
|
7
|
+
[![Build Status](https://secure.travis-ci.org/jsonapi-rb/renderer.svg?branch=master)](http://travis-ci.org/jsonapi-rb/renderer?branch=master)
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
```ruby
|
@@ -53,11 +54,12 @@ class ResourceInterface
|
|
53
54
|
# relationships, or nil.
|
54
55
|
# @return [Hash]
|
55
56
|
def as_jsonapi(options = {}); end
|
57
|
+
end
|
56
58
|
```
|
57
59
|
|
58
60
|
#### Rendering a single resource
|
59
61
|
```ruby
|
60
|
-
JSONAPI.render(resource,
|
62
|
+
JSONAPI.render(data: resource,
|
61
63
|
include: include_string,
|
62
64
|
fields: fields_hash,
|
63
65
|
meta: meta_hash,
|
@@ -68,7 +70,7 @@ This returns a JSON API compliant hash representing the described document.
|
|
68
70
|
|
69
71
|
#### Rendering a collection of resources
|
70
72
|
```ruby
|
71
|
-
JSONAPI.render(resources,
|
73
|
+
JSONAPI.render(data: resources,
|
72
74
|
include: include_string,
|
73
75
|
fields: fields_hash,
|
74
76
|
meta: meta_hash,
|
@@ -80,7 +82,7 @@ This returns a JSON API compliant hash representing the described document.
|
|
80
82
|
### Rendering errors
|
81
83
|
|
82
84
|
```ruby
|
83
|
-
JSONAPI.render_errors(errors,
|
85
|
+
JSONAPI.render_errors(errors: errors,
|
84
86
|
meta: meta_hash,
|
85
87
|
links: links_hash)
|
86
88
|
```
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'jsonapi/include_directive'
|
2
|
+
require 'jsonapi/renderer/resources_processor'
|
3
|
+
|
4
|
+
module JSONAPI
|
5
|
+
module Renderer
|
6
|
+
class Document
|
7
|
+
def initialize(params = {})
|
8
|
+
@data = params.fetch(:data, :no_data)
|
9
|
+
@errors = params.fetch(:errors, [])
|
10
|
+
@meta = params.fetch(:meta, nil)
|
11
|
+
@links = params.fetch(:links, {})
|
12
|
+
@fields = params.fetch(:fields, {})
|
13
|
+
@jsonapi = params.fetch(:jsonapi, nil)
|
14
|
+
@include = JSONAPI::IncludeDirective.new(params.fetch(:include, {}))
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
@hash ||= document_hash
|
19
|
+
end
|
20
|
+
alias to_h to_hash
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def document_hash
|
25
|
+
{}.tap do |hash|
|
26
|
+
if @data != :no_data
|
27
|
+
hash.merge!(data_hash)
|
28
|
+
elsif @errors.any?
|
29
|
+
hash.merge!(errors_hash)
|
30
|
+
end
|
31
|
+
hash[:links] = @links if @links.any?
|
32
|
+
hash[:meta] = @meta unless @meta.nil?
|
33
|
+
hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def data_hash
|
38
|
+
primary, included =
|
39
|
+
ResourcesProcessor.new(Array(@data), @include, @fields).process
|
40
|
+
{}.tap do |hash|
|
41
|
+
hash[:data] = @data.respond_to?(:each) ? primary : primary[0]
|
42
|
+
hash[:included] = included if included.any?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def errors_hash
|
47
|
+
{}.tap do |hash|
|
48
|
+
hash[:errors] = @errors.map(&:as_jsonapi)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Renderer
|
5
|
+
class ResourcesProcessor
|
6
|
+
def initialize(resources, include, fields)
|
7
|
+
@resources = resources
|
8
|
+
@include = include
|
9
|
+
@fields = fields
|
10
|
+
@primary = []
|
11
|
+
@included = []
|
12
|
+
@hashes = {}
|
13
|
+
@queue = []
|
14
|
+
@processed = Set.new # NOTE(beauby): Set of [type, id, prefix].
|
15
|
+
end
|
16
|
+
|
17
|
+
def process
|
18
|
+
@resources.each do |res|
|
19
|
+
process_resource(res, '', @include, true)
|
20
|
+
@processed.add([res.jsonapi_type, res.jsonapi_id, ''])
|
21
|
+
end
|
22
|
+
until @queue.empty?
|
23
|
+
res, prefix, include_dir = @queue.pop
|
24
|
+
process_resource(res, prefix, include_dir, false)
|
25
|
+
end
|
26
|
+
|
27
|
+
[@primary, @included]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def merge_resources!(a, b)
|
33
|
+
b[:relationships].each do |name, rel|
|
34
|
+
a[:relationships][name][:data] ||= rel[:data] if rel.key?(:data)
|
35
|
+
if rel.key?(:links)
|
36
|
+
(a[:relationships][name][:links] ||= {}).merge!(rel[:links])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process_resource(res, prefix, include_dir, is_primary)
|
42
|
+
ri = [res.jsonapi_type, res.jsonapi_id]
|
43
|
+
hash = res.as_jsonapi(fields: @fields[res.jsonapi_type.to_sym],
|
44
|
+
include: include_dir.keys)
|
45
|
+
if @hashes.key?(ri)
|
46
|
+
merge_resources!(@hashes[ri], hash)
|
47
|
+
else
|
48
|
+
(is_primary ? @primary : @included) << (@hashes[ri] = hash)
|
49
|
+
end
|
50
|
+
process_relationships(res, prefix, include_dir)
|
51
|
+
end
|
52
|
+
|
53
|
+
def process_relationships(res, prefix, include_dir)
|
54
|
+
res.jsonapi_related(include_dir.keys).each do |key, data|
|
55
|
+
Array(data).each do |child_res|
|
56
|
+
next if child_res.nil?
|
57
|
+
child_prefix = "#{prefix}.#{key}"
|
58
|
+
next unless @processed.add?([child_res.jsonapi_type,
|
59
|
+
child_res.jsonapi_id,
|
60
|
+
child_prefix])
|
61
|
+
@queue << [child_res, child_prefix, include_dir[key]]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/jsonapi/renderer.rb
CHANGED
@@ -1,98 +1,15 @@
|
|
1
|
-
require 'jsonapi/
|
1
|
+
require 'jsonapi/renderer/document'
|
2
2
|
|
3
3
|
module JSONAPI
|
4
|
-
class Renderer
|
5
|
-
def initialize(resources, options = {})
|
6
|
-
@resources = resources
|
7
|
-
@errors = options[:errors] || false
|
8
|
-
@meta = options[:meta] || nil
|
9
|
-
@links = options[:links] || {}
|
10
|
-
@fields = options[:fields] || {}
|
11
|
-
# NOTE(beauby): Room for some nifty defaults on those.
|
12
|
-
@jsonapi = options[:jsonapi_object] || nil
|
13
|
-
@include = JSONAPI::IncludeDirective.new(options[:include] || {})
|
14
|
-
end
|
15
|
-
|
16
|
-
def as_json
|
17
|
-
return @json unless @json.nil?
|
18
|
-
|
19
|
-
process_resources
|
20
|
-
@json = {}
|
21
|
-
|
22
|
-
if @errors
|
23
|
-
@json[:errors] = @resources.map(&:as_jsonapi)
|
24
|
-
else
|
25
|
-
@json[:data] = @resources.respond_to?(:each) ? @primary : @primary[0]
|
26
|
-
@json[:included] = @included if @included.any?
|
27
|
-
end
|
28
|
-
@json[:links] = @links if @links.any?
|
29
|
-
@json[:meta] = @meta unless @meta.nil?
|
30
|
-
@json[:jsonapi] = @jsonapi unless @jsonapi.nil?
|
31
|
-
|
32
|
-
@json
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def process_resources
|
38
|
-
@primary = []
|
39
|
-
@included = []
|
40
|
-
@hashes = {}
|
41
|
-
@processed = Set.new # NOTE(beauby): Set of [type, id, prefix].
|
42
|
-
@queue = []
|
43
|
-
|
44
|
-
Array(@resources).each do |res|
|
45
|
-
process_resource(res, '', @include, true)
|
46
|
-
@processed.add([res.jsonapi_type, res.jsonapi_id, ''])
|
47
|
-
end
|
48
|
-
until @queue.empty?
|
49
|
-
res, prefix, include_dir = @queue.pop
|
50
|
-
process_resource(res, prefix, include_dir, false)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def merge_resources!(a, b)
|
55
|
-
b[:relationships].each do |name, rel|
|
56
|
-
a[:relationships][name][:data] ||= rel[:data] if rel.key?(:data)
|
57
|
-
(a[:relationships][name][:links] ||= {})
|
58
|
-
.merge!(rel[:links]) if rel.key?(:links)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def process_resource(res, prefix, include_dir, is_primary)
|
63
|
-
ri = [res.jsonapi_type, res.jsonapi_id]
|
64
|
-
hash = res.as_jsonapi(fields: @fields[res.jsonapi_type.to_sym],
|
65
|
-
include: include_dir.keys)
|
66
|
-
if @hashes.key?(ri)
|
67
|
-
merge_resources!(@hashes[ri], hash)
|
68
|
-
else
|
69
|
-
(is_primary ? @primary : @included) << (@hashes[ri] = hash)
|
70
|
-
end
|
71
|
-
process_relationships(res, prefix, include_dir)
|
72
|
-
end
|
73
|
-
|
74
|
-
def process_relationships(res, prefix, include_dir)
|
75
|
-
res.jsonapi_related(include_dir.keys).each do |key, data|
|
76
|
-
Array(data).each do |child_res|
|
77
|
-
next if child_res.nil?
|
78
|
-
child_prefix = "#{prefix}.#{key}"
|
79
|
-
next unless @processed.add?([child_res.jsonapi_type,
|
80
|
-
child_res.jsonapi_id,
|
81
|
-
child_prefix])
|
82
|
-
@queue << [child_res, child_prefix, include_dir[key]]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
4
|
module_function
|
89
5
|
|
90
|
-
# Render a
|
6
|
+
# Render a JSON API document.
|
91
7
|
#
|
92
|
-
# @param [
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
8
|
+
# @param [Hash] params
|
9
|
+
# @option [(#jsonapi_id, #jsonapi_type, #jsonapi_related, #as_jsonapi),
|
10
|
+
# Array<(#jsonapi_id, #jsonapi_type, #jsonapi_related, #as_jsonapi)>,
|
11
|
+
# nil] data Primary resource(s) to be rendered.
|
12
|
+
# @option [Array<#jsonapi_id>] errors Errors to be rendered.
|
96
13
|
# @option [String, Hash{Symbol => Hash}] include Relationships to be
|
97
14
|
# included.
|
98
15
|
# @option [Hash{Symbol, Array<Symbol>}] fields List of requested fields
|
@@ -101,19 +18,7 @@ module JSONAPI
|
|
101
18
|
# included.
|
102
19
|
# @option [Hash] links Top-level links to be included.
|
103
20
|
# @option [Hash] jsonapi_object JSON API object.
|
104
|
-
def render(
|
105
|
-
Renderer.new(
|
106
|
-
end
|
107
|
-
|
108
|
-
# Render an error JSON API document.
|
109
|
-
#
|
110
|
-
# @param [Array<#jsonapi_id>] errors Errors to be rendered.
|
111
|
-
# @param [Hash] options All optional.
|
112
|
-
# @option [Hash] meta Non-standard top-level meta information to be
|
113
|
-
# included.
|
114
|
-
# @option [Hash] links Top-level links to be included.
|
115
|
-
# @option [Hash] jsonapi_object JSON API object.
|
116
|
-
def render_errors(errors)
|
117
|
-
Renderer.new(errors, errors: true).as_json
|
21
|
+
def render(params)
|
22
|
+
Renderer::Document.new(params).to_hash
|
118
23
|
end
|
119
24
|
end
|
metadata
CHANGED
@@ -1,16 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-renderer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.
|
4
|
+
version: 0.1.1.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2016-11-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '11.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '11.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.5'
|
41
|
+
description: Efficiently render JSON API documents.
|
14
42
|
email: lucas.hosseini@gmail.com
|
15
43
|
executables: []
|
16
44
|
extensions: []
|
@@ -20,7 +48,9 @@ files:
|
|
20
48
|
- lib/jsonapi/include_directive.rb
|
21
49
|
- lib/jsonapi/include_directive/parser.rb
|
22
50
|
- lib/jsonapi/renderer.rb
|
23
|
-
|
51
|
+
- lib/jsonapi/renderer/document.rb
|
52
|
+
- lib/jsonapi/renderer/resources_processor.rb
|
53
|
+
homepage: https://github.com/jsonapi-rb/renderer
|
24
54
|
licenses:
|
25
55
|
- MIT
|
26
56
|
metadata: {}
|