jsonapi-serializable 0.1.1.beta1 → 0.1.1.beta2
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 +4 -4
- data/README.md +59 -2
- data/lib/jsonapi/serializable/model.rb +44 -0
- data/lib/jsonapi/serializable/model_dsl.rb +54 -0
- data/lib/jsonapi/serializable/relationship.rb +2 -2
- data/lib/jsonapi/serializable/resource.rb +36 -24
- data/lib/jsonapi/serializable.rb +1 -0
- 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: 9d7beafa6258df4dd44fa02cc22d7a62b8f0e2d0
|
4
|
+
data.tar.gz: fa7223c5647bd81486ec1066e13345a96311081a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e041bc9ebe1a08d945eb721baf612d70166de3cda15a310de8ba860d3f9bb7cd0dc72c2b40a6bf682c7568a0635bf796ed9ebf3676edd47d93ce4c01fcd96e3c
|
7
|
+
data.tar.gz: fd83b712198356d829a7db4b10e2a831d8843a151cfaab7c3a573985a9f8005b2a78f113e0dfbf0b520ca443b18f4194f9635616a8229edf28da847bbbe737a6
|
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# jsonapi-serializable
|
2
|
-
Ruby gem for building
|
3
|
-
|
2
|
+
Ruby gem for building [JSON API](http://jsonapi.org) resources to be rendered by
|
3
|
+
the [jsonapi-renderer](https://github.com/beauby/jsonapi) gem.
|
4
|
+
|
5
|
+
## Status
|
6
|
+
|
7
|
+
[](https://badge.fury.io/rb/jsonapi-serializable)
|
8
|
+
[](http://travis-ci.org/beauby/jsonapi-serializable?branch=master)
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
```ruby
|
@@ -24,6 +29,58 @@ require 'jsonapi/serializable'
|
|
24
29
|
```
|
25
30
|
|
26
31
|
Then, define some resource classes:
|
32
|
+
|
33
|
+
### For model-based resources
|
34
|
+
|
35
|
+
For resources that are simple representations of models, the DSL is simplified:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class PostResource < JSONAPI::Serializable::Resource
|
39
|
+
type 'posts'
|
40
|
+
|
41
|
+
id
|
42
|
+
|
43
|
+
attribute :title
|
44
|
+
|
45
|
+
attribute :date do
|
46
|
+
@model.created_at
|
47
|
+
end
|
48
|
+
|
49
|
+
relationship :author, UserResource do
|
50
|
+
link(:self) do
|
51
|
+
href @url_helper.link_for_rel('posts', @model.id, 'author')
|
52
|
+
meta link_meta: 'some meta'
|
53
|
+
end
|
54
|
+
link(:related) { @url_helper.link_for_res('users', @model.author.id) }
|
55
|
+
meta do
|
56
|
+
{ relationship_meta: 'some meta' }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
has_many :comments
|
61
|
+
|
62
|
+
meta do
|
63
|
+
{ resource_meta: 'some meta' }
|
64
|
+
end
|
65
|
+
|
66
|
+
link(:self) do
|
67
|
+
@url_helper.link_for_res('posts', @model.id)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
Then, build your resources from your models and render them:
|
72
|
+
```ruby
|
73
|
+
# post = some post model
|
74
|
+
# UrlHelper is some helper class
|
75
|
+
resource = PostResource.new(model: post, url_helper: UrlHelper)
|
76
|
+
document = JSONAPI.render(resource)
|
77
|
+
```
|
78
|
+
|
79
|
+
### For general resources
|
80
|
+
|
81
|
+
In case your resource is not a simple representation of one of your models,
|
82
|
+
the more general `JSONAPI::Serializable::Resource` class can be used.
|
83
|
+
|
27
84
|
```ruby
|
28
85
|
class PostResource < JSONAPI::Serializable::Resource
|
29
86
|
type 'posts'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'jsonapi/serializable/model_dsl'
|
2
|
+
require 'jsonapi/serializable/resource'
|
3
|
+
|
4
|
+
module JSONAPI
|
5
|
+
module Serializable
|
6
|
+
class Model < Resource
|
7
|
+
include ModelDSL
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :api_version_val
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.inherited(klass)
|
14
|
+
super
|
15
|
+
klass.api_version_val = api_version_val
|
16
|
+
end
|
17
|
+
|
18
|
+
id { @model.public_send(:id).to_s }
|
19
|
+
|
20
|
+
def resource_klass_for(model_klass)
|
21
|
+
names = model_klass.name.split('::'.freeze)
|
22
|
+
model_klass_name = names.pop
|
23
|
+
namespace = names.join('::'.freeze)
|
24
|
+
version = self.class.api_version_val
|
25
|
+
|
26
|
+
klass_name = [namespace, version, "Serializable#{model_klass_name}"]
|
27
|
+
.reject(&:nil?)
|
28
|
+
.reject(&:empty?)
|
29
|
+
.join('::'.freeze)
|
30
|
+
|
31
|
+
Object.const_get(klass_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def nil?
|
35
|
+
@model.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def as_jsonapi(params = {})
|
39
|
+
return nil if nil?
|
40
|
+
super(params)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Serializable
|
3
|
+
module ModelDSL
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def api_version(value)
|
10
|
+
self.api_version_val = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def type(value = nil)
|
14
|
+
value ||= name
|
15
|
+
super(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def attribute(attr, &block)
|
19
|
+
block ||= proc { @model.public_send(attr) }
|
20
|
+
super(attr, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_many(rel, resource_klass = nil, &block)
|
24
|
+
rel_block = proc do
|
25
|
+
if resource_klass
|
26
|
+
data do
|
27
|
+
@model.public_send(rel).map do |related|
|
28
|
+
resource_klass ||= resource_klass_for(related.class)
|
29
|
+
resource_klass.new(model: related)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
instance_eval(&block) unless block.nil?
|
34
|
+
end
|
35
|
+
relationship(rel, &rel_block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_one(rel, resource_klass = nil, &block)
|
39
|
+
rel_block = proc do
|
40
|
+
if resource_klass
|
41
|
+
data do
|
42
|
+
related = @model.public_send(rel)
|
43
|
+
resource_klass ||= resource_klass_for(related.class)
|
44
|
+
resource_klass.new(model: related)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
instance_eval(&block) unless block.nil?
|
48
|
+
end
|
49
|
+
relationship(rel, &rel_block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -17,8 +17,8 @@ module JSONAPI
|
|
17
17
|
hash = {}
|
18
18
|
hash[:links] = @_links if @_links.any?
|
19
19
|
hash[:meta] = @_meta unless @_meta.nil?
|
20
|
-
hash
|
21
|
-
|
20
|
+
return hash unless included || (!@_links.any? && @_meta.nil?)
|
21
|
+
hash[:data] = eval_linkage_data
|
22
22
|
|
23
23
|
hash
|
24
24
|
end
|
@@ -18,51 +18,43 @@ module JSONAPI
|
|
18
18
|
|
19
19
|
def self.inherited(klass)
|
20
20
|
super
|
21
|
+
klass.type_val = type_val
|
22
|
+
klass.type_block = type_block
|
23
|
+
klass.id_block = id_block
|
24
|
+
klass.meta_val = meta_val
|
25
|
+
klass.meta_block = meta_block
|
21
26
|
klass.attribute_blocks = attribute_blocks.dup
|
22
27
|
klass.relationship_blocks = relationship_blocks.dup
|
23
28
|
klass.link_blocks = link_blocks.dup
|
24
29
|
end
|
25
30
|
|
26
31
|
def initialize(param_hash = {})
|
32
|
+
@_param_hash = param_hash
|
27
33
|
param_hash.each { |k, v| instance_variable_set("@#{k}", v) }
|
28
|
-
@_id = instance_eval(&self.class.id_block)
|
29
|
-
@_type = self.class.type_val || instance_eval(&self.class.type_block)
|
30
|
-
@_meta = if self.class.meta_val
|
31
|
-
self.class.meta_val
|
32
|
-
elsif self.class.meta_block
|
33
|
-
instance_eval(&self.class.meta_block)
|
34
|
-
end
|
35
|
-
@_attributes = {}
|
36
|
-
@_relationships = self.class.relationship_blocks
|
37
|
-
.each_with_object({}) do |(k, v), h|
|
38
|
-
h[k] = Relationship.new(param_hash, &v)
|
39
|
-
end
|
40
|
-
@_links = self.class.link_blocks.each_with_object({}) do |(k, v), h|
|
41
|
-
h[k] = Link.as_jsonapi(param_hash, &v)
|
42
|
-
end
|
43
34
|
end
|
44
35
|
|
45
36
|
def as_jsonapi(params = {})
|
46
37
|
hash = {}
|
47
|
-
hash[:id] =
|
48
|
-
hash[:type] =
|
49
|
-
|
38
|
+
hash[:id] = jsonapi_id
|
39
|
+
hash[:type] = jsonapi_type
|
40
|
+
requested_attrs = params[:fields] || self.class.attribute_blocks.keys
|
41
|
+
attr = attributes(requested_attrs)
|
50
42
|
hash[:attributes] = attr if attr.any?
|
51
|
-
|
52
|
-
|
43
|
+
requested_rels = params[:fields] || self.class.relationship_blocks.keys
|
44
|
+
rels = relationships(requested_rels, params[:include] || [])
|
53
45
|
hash[:relationships] = rels if rels.any?
|
54
|
-
hash[:links] =
|
55
|
-
hash[:meta] =
|
46
|
+
hash[:links] = links if links.any?
|
47
|
+
hash[:meta] = meta unless meta.nil?
|
56
48
|
|
57
49
|
hash
|
58
50
|
end
|
59
51
|
|
60
52
|
def jsonapi_type
|
61
|
-
@_type
|
53
|
+
@_type ||= self.class.type_val || instance_eval(&self.class.type_block)
|
62
54
|
end
|
63
55
|
|
64
56
|
def jsonapi_id
|
65
|
-
@_id
|
57
|
+
@_id ||= instance_eval(&self.class.id_block)
|
66
58
|
end
|
67
59
|
|
68
60
|
def jsonapi_related(include)
|
@@ -74,6 +66,7 @@ module JSONAPI
|
|
74
66
|
private
|
75
67
|
|
76
68
|
def attributes(fields)
|
69
|
+
@_attributes ||= {}
|
77
70
|
self.class.attribute_blocks
|
78
71
|
.select { |k, _| !@_attributes.key?(k) && fields.include?(k) }
|
79
72
|
.each { |k, v| @_attributes[k] = instance_eval(&v) }
|
@@ -81,12 +74,31 @@ module JSONAPI
|
|
81
74
|
end
|
82
75
|
|
83
76
|
def relationships(fields, include)
|
77
|
+
@_relationships ||= self.class.relationship_blocks
|
78
|
+
.each_with_object({}) do |(k, v), h|
|
79
|
+
h[k] = Relationship.new(@_param_hash, &v)
|
80
|
+
end
|
84
81
|
@_relationships
|
85
82
|
.select { |k, _| fields.include?(k) }
|
86
83
|
.each_with_object({}) do |(k, v), h|
|
87
84
|
h[k] = v.as_jsonapi(include.include?(k))
|
88
85
|
end
|
89
86
|
end
|
87
|
+
|
88
|
+
def meta
|
89
|
+
@_meta ||=
|
90
|
+
if self.class.meta_val
|
91
|
+
self.class.meta_val
|
92
|
+
elsif self.class.meta_block
|
93
|
+
instance_eval(&self.class.meta_block)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def links
|
98
|
+
@_links ||= self.class.link_blocks.each_with_object({}) do |(k, v), h|
|
99
|
+
h[k] = Link.as_jsonapi(@_param_hash, &v)
|
100
|
+
end
|
101
|
+
end
|
90
102
|
end
|
91
103
|
end
|
92
104
|
end
|
data/lib/jsonapi/serializable.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-serializable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.
|
4
|
+
version: 0.1.1.beta2
|
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-10-
|
11
|
+
date: 2016-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jsonapi-renderer
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.1.beta2
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.1.beta2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
16
44
|
requirements:
|
17
45
|
- - "~>"
|
18
46
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
21
49
|
prerelease: false
|
22
50
|
version_requirements: !ruby/object:Gem::Requirement
|
23
51
|
requirements:
|
24
52
|
- - "~>"
|
25
53
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
54
|
+
version: '3.4'
|
27
55
|
description: DSL for building resource classes to be rendered by jsonapi-renderer.
|
28
56
|
email: lucas.hosseini@gmail.com
|
29
57
|
executables: []
|
@@ -35,6 +63,8 @@ files:
|
|
35
63
|
- lib/jsonapi/serializable/error.rb
|
36
64
|
- lib/jsonapi/serializable/error_dsl.rb
|
37
65
|
- lib/jsonapi/serializable/link.rb
|
66
|
+
- lib/jsonapi/serializable/model.rb
|
67
|
+
- lib/jsonapi/serializable/model_dsl.rb
|
38
68
|
- lib/jsonapi/serializable/relationship.rb
|
39
69
|
- lib/jsonapi/serializable/relationship_dsl.rb
|
40
70
|
- lib/jsonapi/serializable/resource.rb
|