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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70a2dc4601aee95d0b8ca23f13996aa12f55d697
4
- data.tar.gz: d9b52897b675d77b5b353195eea2f1bd1c610c33
3
+ metadata.gz: 26aca00f45d33183b7dd675cb65cc5c0de391c23
4
+ data.tar.gz: 8a10856e79d6c6190bd9834a50a8f7d3b6b12356
5
5
  SHA512:
6
- metadata.gz: 01e2a4136d074192f60bb7c54b0f159bec76ae83be357ff97cd2505a6385dec091b6cce68ce23b7a88ab376360d94a70b6fa5b797759e25439edfbb900fd6646
7
- data.tar.gz: 983f533a18b6c30f28bf4ddc353e3ffc899d389582f60010610bcf610adcc2f1820470811e5f48dad70d376f878fb93e71d5b691db048487059a9434094c8c20
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 JsonApi::Serializer
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
- TODO: Write usage instructions here
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 Serializer
8
- def to_json(object, **options)
9
- ActiveSupport::JSON.encode({ data: data_for(object, **options) })
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
- canonicalize_type_name(object.class.name)
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/serializer'
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
- Serializer.new.to_json(object, {
8
- id_attribute: id_attribute,
9
- attributes: attributes,
10
- relationships: relationships
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
- options[:type] || options[:name]
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 key_for(options)
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
@@ -0,0 +1,3 @@
1
+ module JSONApi
2
+ VERSION = '0.2.0'
3
+ 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.1.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-18 00:00:00.000000000 Z
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.5.1
115
+ rubygems_version: 2.4.6
114
116
  signing_key:
115
117
  specification_version: 4
116
118
  summary: An extremely simple JSON Api serializer