simple-json-api-serializer 0.1.0 → 0.2.0
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/.gitignore +1 -0
- data/README.md +125 -4
- data/lib/json_api/{serializer.rb → object_serializer.rb} +20 -8
- data/lib/json_api/object_serializer_definition.rb +7 -7
- data/lib/json_api/relationship_serializer.rb +15 -5
- data/lib/json_api/version.rb +3 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26aca00f45d33183b7dd675cb65cc5c0de391c23
|
4
|
+
data.tar.gz: 8a10856e79d6c6190bd9834a50a8f7d3b6b12356
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c017a9d09bee70bdeee9bd188734b8e23a082ee32f67d61fb785f4e620a45ce50b5eb84feb59f4a0ba5218748fd5d7a9712f4d0b8cf12cb75b469a1c0507123
|
7
|
+
data.tar.gz: 49970b68ac24fcc874013197ede703328a02e7dc366cce35ac79d721f2d3738bfe30bc7f9846e10322b4ecd0ac98abce899c83bb826ec9e0c6440ce86b425631
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.*vimrc
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
# Simple
|
2
|
-
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/simple/json/api/serializer`. To experiment with that code, run `bin/console` for an interactive prompt.
|
1
|
+
# Simple JSONApi::Serializer
|
4
2
|
|
3
|
+
* An extremely simple JSON Api serializer.
|
4
|
+
* It supports serializing any Ruby object.
|
5
|
+
* It does not target a specific framework.
|
6
|
+
* Does not (yet) support links and includes.
|
5
7
|
|
6
8
|
## Installation
|
7
9
|
|
@@ -21,7 +23,126 @@ Or install it yourself as:
|
|
21
23
|
|
22
24
|
## Usage
|
23
25
|
|
24
|
-
|
26
|
+
You can use the JSONApi::Serializer in two ways:
|
27
|
+
* In a DSL like manner by declaring your configuration in as subclass of `JSONApi::ObjectSerializerDefinition`
|
28
|
+
* By using `JSONApi::Serializer#to_json` directly with an object and a configuration hash
|
29
|
+
|
30
|
+
### The DSL way
|
31
|
+
|
32
|
+
The simplest serializer you can declare looks like this:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
class MyObjectSerializer < JSONApi::ObjectSerializerDefinition
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
You can then serialize objects with it:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
MyObject = Struct.new(:id)
|
43
|
+
my_object = MyObject.new(1)
|
44
|
+
|
45
|
+
MyObjectSerializer.serialize(my_object)
|
46
|
+
```
|
47
|
+
|
48
|
+
Which generates:
|
49
|
+
|
50
|
+
```json
|
51
|
+
{
|
52
|
+
"data": {
|
53
|
+
"type": "my-objects",
|
54
|
+
"id": "1"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
#### Configuring the output
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class PersonSerializer < JSONApi::ObjectSerializerDefinition
|
63
|
+
id_attribute :ssn
|
64
|
+
|
65
|
+
attributes :first_name, :last_name
|
66
|
+
end
|
67
|
+
|
68
|
+
Person = Struct.new(:ssn, :first_name, :last_name)
|
69
|
+
joe = Person.new('X3DAB4CFJ0', 'Joe', 'Strummer')
|
70
|
+
|
71
|
+
PersonSerializer.serialize(joe)
|
72
|
+
```
|
73
|
+
|
74
|
+
Generates:
|
75
|
+
|
76
|
+
```json
|
77
|
+
{
|
78
|
+
"data": {
|
79
|
+
"type": "persons",
|
80
|
+
"id": "X3DAB4CFJ0",
|
81
|
+
"attributes": {
|
82
|
+
"first-name": "Joe",
|
83
|
+
"last-name": "Strummer"
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
#### Adding relationships
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
class PostSerializer < JSONApi::ObjectSerializerDefinition
|
93
|
+
attributes :title, :content
|
94
|
+
|
95
|
+
has_one :author
|
96
|
+
has_many :comments
|
97
|
+
end
|
98
|
+
|
99
|
+
Post = Struct.new(:id, :title, :content, :author, :comments) do
|
100
|
+
def author_id
|
101
|
+
author.id
|
102
|
+
end
|
103
|
+
|
104
|
+
def comment_ids
|
105
|
+
comments.map(&:id)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
post = Post.new(1, "How to serialize objects", "...", author, comments)
|
110
|
+
|
111
|
+
PostSerializer.serialize(post)
|
112
|
+
```
|
113
|
+
|
114
|
+
Generates:
|
115
|
+
|
116
|
+
```json
|
117
|
+
{
|
118
|
+
"data": {
|
119
|
+
"type": "posts",
|
120
|
+
"id": "1",
|
121
|
+
"attributes": {
|
122
|
+
"title": "How to serialize objects",
|
123
|
+
"content": "...",
|
124
|
+
},
|
125
|
+
"relationships": {
|
126
|
+
"author": {
|
127
|
+
"data": { "type": "authors", "id": "42" },
|
128
|
+
},
|
129
|
+
"comments": {
|
130
|
+
"data": [
|
131
|
+
{ "type": "comments", "id": "1" },
|
132
|
+
{ "type": "comments", "id": "2" }
|
133
|
+
]
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
```
|
139
|
+
|
140
|
+
If your object does not abide by the `_id` or `_ids` convention for relations,
|
141
|
+
you can specify what method should be called to retrieve the foreign key with
|
142
|
+
`has_one :author, foreign_key: :username`
|
143
|
+
|
144
|
+
You can also specify the type of the related object with: `has_one :author, type: :user`.
|
145
|
+
|
25
146
|
|
26
147
|
## Development
|
27
148
|
|
@@ -4,9 +4,15 @@ require 'json_api/relationship_serializer'
|
|
4
4
|
|
5
5
|
|
6
6
|
module JSONApi
|
7
|
-
class
|
8
|
-
def
|
9
|
-
|
7
|
+
class ObjectSerializer
|
8
|
+
def serialize(object, **options)
|
9
|
+
hash = { data: data_for(object, **options) }
|
10
|
+
|
11
|
+
if options[:include].is_a?(Array)
|
12
|
+
hash[:included] = options[:include]
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveSupport::JSON.encode(hash)
|
10
16
|
end
|
11
17
|
|
12
18
|
private
|
@@ -34,10 +40,15 @@ module JSONApi
|
|
34
40
|
end
|
35
41
|
|
36
42
|
def resource_identifier_for(object, **options)
|
37
|
-
{
|
38
|
-
type: type_for(object)
|
39
|
-
id: id_for(object, options)
|
43
|
+
resource_identifier = {
|
44
|
+
type: type_for(object, options)
|
40
45
|
}
|
46
|
+
|
47
|
+
unless options[:new_record]
|
48
|
+
resource_identifier[:id] = id_for(object, options)
|
49
|
+
end
|
50
|
+
|
51
|
+
resource_identifier
|
41
52
|
end
|
42
53
|
|
43
54
|
def relationships_for(object, options)
|
@@ -61,8 +72,9 @@ module JSONApi
|
|
61
72
|
canonicalize_id(object.send(id_attribute))
|
62
73
|
end
|
63
74
|
|
64
|
-
def type_for(object)
|
65
|
-
|
75
|
+
def type_for(object, **options)
|
76
|
+
type_name = options[:type] || object.class.name
|
77
|
+
canonicalize_type_name(type_name)
|
66
78
|
end
|
67
79
|
|
68
80
|
def canonicalize_id(id)
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require 'json_api/
|
1
|
+
require 'json_api/object_serializer'
|
2
2
|
|
3
3
|
module JSONApi
|
4
4
|
class ObjectSerializerDefinition
|
5
5
|
class << self
|
6
|
-
def serialize(object)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
def serialize(object, **options)
|
7
|
+
options[:id_attribute] ||= id_attribute
|
8
|
+
options[:attributes] ||= attributes
|
9
|
+
options[:relationships] ||= relationships
|
10
|
+
|
11
|
+
ObjectSerializer.new.serialize(object, **options)
|
12
12
|
end
|
13
13
|
|
14
14
|
def inherited(specialization)
|
@@ -19,14 +19,24 @@ module JSONApi
|
|
19
19
|
|
20
20
|
protected
|
21
21
|
|
22
|
-
def type_for(options)
|
23
|
-
|
22
|
+
def type_for(object, options)
|
23
|
+
if options[:polymorphic]
|
24
|
+
foreign_type_key =
|
25
|
+
options[:foreign_type_key] || "#{key_base_for(options)}_type"
|
26
|
+
object.send(foreign_type_key)
|
27
|
+
else
|
28
|
+
options[:type] || options[:name]
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
|
-
def
|
32
|
+
def key_base_for(options)
|
27
33
|
options[:name].to_s.singularize
|
28
34
|
end
|
29
35
|
|
36
|
+
def key_for(options)
|
37
|
+
key_base_for(options)
|
38
|
+
end
|
39
|
+
|
30
40
|
def relationship_for(object, **options)
|
31
41
|
object.send(options[:key] || key_for(options))
|
32
42
|
end
|
@@ -47,7 +57,7 @@ module JSONApi
|
|
47
57
|
|
48
58
|
def data_for(object, options)
|
49
59
|
ids = relationship_for(object, options)
|
50
|
-
ids.map { |id| resource_identifier_for(type_for(options), id) }
|
60
|
+
ids.map { |id| resource_identifier_for(type_for(object, options), id) }
|
51
61
|
.compact
|
52
62
|
end
|
53
63
|
end
|
@@ -59,7 +69,7 @@ module JSONApi
|
|
59
69
|
|
60
70
|
def data_for(object, options)
|
61
71
|
id = relationship_for(object, options)
|
62
|
-
resource_identifier_for(type_for(options), id)
|
72
|
+
resource_identifier_for(type_for(object, options), id)
|
63
73
|
end
|
64
74
|
end
|
65
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-json-api-serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marten Schilstra
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -75,6 +75,7 @@ executables: []
|
|
75
75
|
extensions: []
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
|
+
- ".gitignore"
|
78
79
|
- CODE_OF_CONDUCT.md
|
79
80
|
- Gemfile
|
80
81
|
- Gemfile.lock
|
@@ -83,10 +84,11 @@ files:
|
|
83
84
|
- Rakefile
|
84
85
|
- bin/console
|
85
86
|
- bin/setup
|
87
|
+
- lib/json_api/object_serializer.rb
|
86
88
|
- lib/json_api/object_serializer_definition.rb
|
87
89
|
- lib/json_api/relationship_serializer.rb
|
88
|
-
- lib/json_api/serializer.rb
|
89
90
|
- lib/json_api/utils.rb
|
91
|
+
- lib/json_api/version.rb
|
90
92
|
- lib/simple/json/api/serializer.rb
|
91
93
|
- lib/simple/json/api/serializer/version.rb
|
92
94
|
- simple-json-api-serializer.gemspec
|
@@ -110,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
112
|
version: '0'
|
111
113
|
requirements: []
|
112
114
|
rubyforge_project:
|
113
|
-
rubygems_version: 2.4.
|
115
|
+
rubygems_version: 2.4.6
|
114
116
|
signing_key:
|
115
117
|
specification_version: 4
|
116
118
|
summary: An extremely simple JSON Api serializer
|