jsonapi-serializable 0.1.1.beta1 → 0.1.1.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/jsonapi-serializable.svg)](https://badge.fury.io/rb/jsonapi-serializable)
|
8
|
+
[![Build Status](https://secure.travis-ci.org/beauby/jsonapi-serializable.svg?branch=master)](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
|