media_types-serialization 1.2.0 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +137 -137
- data/README.md +133 -59
- data/lib/media_types/serialization.rb +44 -26
- data/lib/media_types/serialization/base.rb +90 -25
- data/lib/media_types/serialization/fake_validator.rb +1 -0
- data/lib/media_types/serialization/serialization_dsl.rb +3 -3
- data/lib/media_types/serialization/serialization_registration.rb +2 -2
- data/lib/media_types/serialization/version.rb +1 -1
- data/media_types-serialization.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 737a38bc10cd0c3aff8fa9bc33c3c192098709eb331f7c35706840410ff3d280
|
4
|
+
data.tar.gz: d6311d9a1b27329e4164cb7bf3b8e839ce96419b05e9a9e42d033d7ba2942a50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6fad7b09ecc516290fb5e0393ee5a790c128a75402cdb977c396b6dac01b30748b63f5631b001b7eaa9d9c1b8007e814200d9be7766afa757d1c93785bc34f8
|
7
|
+
data.tar.gz: ea95bb41414b2125ac3af7efe42ff9c5e521f36a7bae2930760dd52fdee3e58e1175e5aaa8f03d3eb27bf5022d089f0542f4bc51b418cee05ae3724ba3756779
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.3.4
|
4
|
+
|
5
|
+
- Same as `1.3.3`
|
6
|
+
|
7
|
+
## 1.3.3
|
8
|
+
|
9
|
+
- 🐛 Fix override suffix not being picked up correctly
|
10
|
+
- 🐛 Fix inability to override suffix for aliases
|
11
|
+
- 🐛 Fix inability to override suffix for raw
|
12
|
+
- 🐛 Fix default suffix for raw
|
13
|
+
|
14
|
+
## 1.3.2
|
15
|
+
|
16
|
+
- 🐛 Fix override suffix not returning self or new
|
17
|
+
|
18
|
+
## 1.3.1
|
19
|
+
|
20
|
+
- 🐛 Fix api viewer
|
21
|
+
- 🐛 Fix `output_raw` suffix (`+json` needs to be `''`)
|
22
|
+
|
23
|
+
## 1.3.0
|
24
|
+
|
25
|
+
- ✨ Add `formats:` to `output_html` and default it to `[:html]`, so rails behaves
|
26
|
+
- 🐛 Fix stale references to `render media:`
|
27
|
+
- 🐛 Fix inconsistent `context:` passing for `Serializer.serialize`
|
28
|
+
|
3
29
|
## 1.2.0
|
4
30
|
|
5
31
|
- ✨ Add `view:` to `output_html` which renders a specific rails view.
|
data/Gemfile.lock
CHANGED
@@ -1,137 +1,137 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
media_types-serialization (1.
|
5
|
-
actionpack (>= 4.0.0)
|
6
|
-
activesupport (>= 4.0.0)
|
7
|
-
media_types (>= 2.
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: https://rubygems.org/
|
11
|
-
specs:
|
12
|
-
actioncable (5.2.6)
|
13
|
-
actionpack (= 5.2.6)
|
14
|
-
nio4r (~> 2.0)
|
15
|
-
websocket-driver (>= 0.6.1)
|
16
|
-
actionmailer (5.2.6)
|
17
|
-
actionpack (= 5.2.6)
|
18
|
-
actionview (= 5.2.6)
|
19
|
-
activejob (= 5.2.6)
|
20
|
-
mail (~> 2.5, >= 2.5.4)
|
21
|
-
rails-dom-testing (~> 2.0)
|
22
|
-
actionpack (5.2.6)
|
23
|
-
actionview (= 5.2.6)
|
24
|
-
activesupport (= 5.2.6)
|
25
|
-
rack (~> 2.0, >= 2.0.8)
|
26
|
-
rack-test (>= 0.6.3)
|
27
|
-
rails-dom-testing (~> 2.0)
|
28
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
29
|
-
actionview (5.2.6)
|
30
|
-
activesupport (= 5.2.6)
|
31
|
-
builder (~> 3.1)
|
32
|
-
erubi (~> 1.4)
|
33
|
-
rails-dom-testing (~> 2.0)
|
34
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
35
|
-
activejob (5.2.6)
|
36
|
-
activesupport (= 5.2.6)
|
37
|
-
globalid (>= 0.3.6)
|
38
|
-
activemodel (5.2.6)
|
39
|
-
activesupport (= 5.2.6)
|
40
|
-
activerecord (5.2.6)
|
41
|
-
activemodel (= 5.2.6)
|
42
|
-
activesupport (= 5.2.6)
|
43
|
-
arel (>= 9.0)
|
44
|
-
activestorage (5.2.6)
|
45
|
-
actionpack (= 5.2.6)
|
46
|
-
activerecord (= 5.2.6)
|
47
|
-
marcel (~> 1.0.0)
|
48
|
-
activesupport (5.2.6)
|
49
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
50
|
-
i18n (>= 0.7, < 2)
|
51
|
-
minitest (~> 5.1)
|
52
|
-
tzinfo (~> 1.1)
|
53
|
-
arel (9.0.0)
|
54
|
-
awesome_print (1.9.2)
|
55
|
-
builder (3.2.4)
|
56
|
-
concurrent-ruby (1.1.9)
|
57
|
-
crass (1.0.6)
|
58
|
-
erubi (1.10.0)
|
59
|
-
globalid (0.
|
60
|
-
activesupport (>=
|
61
|
-
i18n (1.8.10)
|
62
|
-
concurrent-ruby (~> 1.0)
|
63
|
-
loofah (2.
|
64
|
-
crass (~> 1.0.2)
|
65
|
-
nokogiri (>= 1.5.9)
|
66
|
-
mail (2.7.1)
|
67
|
-
mini_mime (>= 0.1.1)
|
68
|
-
marcel (1.0.1)
|
69
|
-
media_types (2.0
|
70
|
-
method_source (1.0.0)
|
71
|
-
mini_mime (1.1.0)
|
72
|
-
minitest (5.14.4)
|
73
|
-
nio4r (2.5.
|
74
|
-
nokogiri (1.
|
75
|
-
racc (~> 1.4)
|
76
|
-
nokogiri (1.
|
77
|
-
racc (~> 1.4)
|
78
|
-
oj (3.
|
79
|
-
racc (1.5.2)
|
80
|
-
rack (2.2.3)
|
81
|
-
rack-test (1.1.0)
|
82
|
-
rack (>= 1.0, < 3)
|
83
|
-
rails (5.2.6)
|
84
|
-
actioncable (= 5.2.6)
|
85
|
-
actionmailer (= 5.2.6)
|
86
|
-
actionpack (= 5.2.6)
|
87
|
-
actionview (= 5.2.6)
|
88
|
-
activejob (= 5.2.6)
|
89
|
-
activemodel (= 5.2.6)
|
90
|
-
activerecord (= 5.2.6)
|
91
|
-
activestorage (= 5.2.6)
|
92
|
-
activesupport (= 5.2.6)
|
93
|
-
bundler (>= 1.3.0)
|
94
|
-
railties (= 5.2.6)
|
95
|
-
sprockets-rails (>= 2.0.0)
|
96
|
-
rails-dom-testing (2.0.3)
|
97
|
-
activesupport (>= 4.2.0)
|
98
|
-
nokogiri (>= 1.6)
|
99
|
-
rails-html-sanitizer (1.3.0)
|
100
|
-
loofah (~> 2.3)
|
101
|
-
railties (5.2.6)
|
102
|
-
actionpack (= 5.2.6)
|
103
|
-
activesupport (= 5.2.6)
|
104
|
-
method_source
|
105
|
-
rake (>= 0.8.7)
|
106
|
-
thor (>= 0.19.0, < 2.0)
|
107
|
-
rake (13.0.6)
|
108
|
-
sprockets (4.0.2)
|
109
|
-
concurrent-ruby (~> 1.0)
|
110
|
-
rack (> 1, < 3)
|
111
|
-
sprockets-rails (3.2.2)
|
112
|
-
actionpack (>= 4.0)
|
113
|
-
activesupport (>= 4.0)
|
114
|
-
sprockets (>= 3.0.0)
|
115
|
-
thor (1.1.0)
|
116
|
-
thread_safe (0.3.6)
|
117
|
-
tzinfo (1.2.9)
|
118
|
-
thread_safe (~> 0.1)
|
119
|
-
websocket-driver (0.7.5)
|
120
|
-
websocket-extensions (>= 0.1.0)
|
121
|
-
websocket-extensions (0.1.5)
|
122
|
-
|
123
|
-
PLATFORMS
|
124
|
-
x64-mingw32
|
125
|
-
x86_64-linux
|
126
|
-
|
127
|
-
DEPENDENCIES
|
128
|
-
awesome_print
|
129
|
-
bundler
|
130
|
-
media_types-serialization!
|
131
|
-
minitest (~> 5.0)
|
132
|
-
oj
|
133
|
-
rails (~> 5.2)
|
134
|
-
rake (~> 13.0)
|
135
|
-
|
136
|
-
BUNDLED WITH
|
137
|
-
2.2.7
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
media_types-serialization (1.3.4)
|
5
|
+
actionpack (>= 4.0.0)
|
6
|
+
activesupport (>= 4.0.0)
|
7
|
+
media_types (>= 2.1.0, < 3.0.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actioncable (5.2.6)
|
13
|
+
actionpack (= 5.2.6)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
actionmailer (5.2.6)
|
17
|
+
actionpack (= 5.2.6)
|
18
|
+
actionview (= 5.2.6)
|
19
|
+
activejob (= 5.2.6)
|
20
|
+
mail (~> 2.5, >= 2.5.4)
|
21
|
+
rails-dom-testing (~> 2.0)
|
22
|
+
actionpack (5.2.6)
|
23
|
+
actionview (= 5.2.6)
|
24
|
+
activesupport (= 5.2.6)
|
25
|
+
rack (~> 2.0, >= 2.0.8)
|
26
|
+
rack-test (>= 0.6.3)
|
27
|
+
rails-dom-testing (~> 2.0)
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
29
|
+
actionview (5.2.6)
|
30
|
+
activesupport (= 5.2.6)
|
31
|
+
builder (~> 3.1)
|
32
|
+
erubi (~> 1.4)
|
33
|
+
rails-dom-testing (~> 2.0)
|
34
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
35
|
+
activejob (5.2.6)
|
36
|
+
activesupport (= 5.2.6)
|
37
|
+
globalid (>= 0.3.6)
|
38
|
+
activemodel (5.2.6)
|
39
|
+
activesupport (= 5.2.6)
|
40
|
+
activerecord (5.2.6)
|
41
|
+
activemodel (= 5.2.6)
|
42
|
+
activesupport (= 5.2.6)
|
43
|
+
arel (>= 9.0)
|
44
|
+
activestorage (5.2.6)
|
45
|
+
actionpack (= 5.2.6)
|
46
|
+
activerecord (= 5.2.6)
|
47
|
+
marcel (~> 1.0.0)
|
48
|
+
activesupport (5.2.6)
|
49
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
50
|
+
i18n (>= 0.7, < 2)
|
51
|
+
minitest (~> 5.1)
|
52
|
+
tzinfo (~> 1.1)
|
53
|
+
arel (9.0.0)
|
54
|
+
awesome_print (1.9.2)
|
55
|
+
builder (3.2.4)
|
56
|
+
concurrent-ruby (1.1.9)
|
57
|
+
crass (1.0.6)
|
58
|
+
erubi (1.10.0)
|
59
|
+
globalid (0.5.2)
|
60
|
+
activesupport (>= 5.0)
|
61
|
+
i18n (1.8.10)
|
62
|
+
concurrent-ruby (~> 1.0)
|
63
|
+
loofah (2.12.0)
|
64
|
+
crass (~> 1.0.2)
|
65
|
+
nokogiri (>= 1.5.9)
|
66
|
+
mail (2.7.1)
|
67
|
+
mini_mime (>= 0.1.1)
|
68
|
+
marcel (1.0.1)
|
69
|
+
media_types (2.1.0)
|
70
|
+
method_source (1.0.0)
|
71
|
+
mini_mime (1.1.0)
|
72
|
+
minitest (5.14.4)
|
73
|
+
nio4r (2.5.8)
|
74
|
+
nokogiri (1.12.3-x64-mingw32)
|
75
|
+
racc (~> 1.4)
|
76
|
+
nokogiri (1.12.3-x86_64-linux)
|
77
|
+
racc (~> 1.4)
|
78
|
+
oj (3.13.1)
|
79
|
+
racc (1.5.2)
|
80
|
+
rack (2.2.3)
|
81
|
+
rack-test (1.1.0)
|
82
|
+
rack (>= 1.0, < 3)
|
83
|
+
rails (5.2.6)
|
84
|
+
actioncable (= 5.2.6)
|
85
|
+
actionmailer (= 5.2.6)
|
86
|
+
actionpack (= 5.2.6)
|
87
|
+
actionview (= 5.2.6)
|
88
|
+
activejob (= 5.2.6)
|
89
|
+
activemodel (= 5.2.6)
|
90
|
+
activerecord (= 5.2.6)
|
91
|
+
activestorage (= 5.2.6)
|
92
|
+
activesupport (= 5.2.6)
|
93
|
+
bundler (>= 1.3.0)
|
94
|
+
railties (= 5.2.6)
|
95
|
+
sprockets-rails (>= 2.0.0)
|
96
|
+
rails-dom-testing (2.0.3)
|
97
|
+
activesupport (>= 4.2.0)
|
98
|
+
nokogiri (>= 1.6)
|
99
|
+
rails-html-sanitizer (1.3.0)
|
100
|
+
loofah (~> 2.3)
|
101
|
+
railties (5.2.6)
|
102
|
+
actionpack (= 5.2.6)
|
103
|
+
activesupport (= 5.2.6)
|
104
|
+
method_source
|
105
|
+
rake (>= 0.8.7)
|
106
|
+
thor (>= 0.19.0, < 2.0)
|
107
|
+
rake (13.0.6)
|
108
|
+
sprockets (4.0.2)
|
109
|
+
concurrent-ruby (~> 1.0)
|
110
|
+
rack (> 1, < 3)
|
111
|
+
sprockets-rails (3.2.2)
|
112
|
+
actionpack (>= 4.0)
|
113
|
+
activesupport (>= 4.0)
|
114
|
+
sprockets (>= 3.0.0)
|
115
|
+
thor (1.1.0)
|
116
|
+
thread_safe (0.3.6)
|
117
|
+
tzinfo (1.2.9)
|
118
|
+
thread_safe (~> 0.1)
|
119
|
+
websocket-driver (0.7.5)
|
120
|
+
websocket-extensions (>= 0.1.0)
|
121
|
+
websocket-extensions (0.1.5)
|
122
|
+
|
123
|
+
PLATFORMS
|
124
|
+
x64-mingw32
|
125
|
+
x86_64-linux
|
126
|
+
|
127
|
+
DEPENDENCIES
|
128
|
+
awesome_print
|
129
|
+
bundler
|
130
|
+
media_types-serialization!
|
131
|
+
minitest (~> 5.0)
|
132
|
+
oj
|
133
|
+
rails (~> 5.2)
|
134
|
+
rake (~> 13.0)
|
135
|
+
|
136
|
+
BUNDLED WITH
|
137
|
+
2.2.7
|
data/README.md
CHANGED
@@ -79,11 +79,13 @@ class BookController < ActionController::API
|
|
79
79
|
end
|
80
80
|
```
|
81
81
|
|
82
|
-
While using the controller integration the context will always be set to the current controller.
|
82
|
+
While using the controller integration the context will always be set to the current controller.
|
83
|
+
This allows you to construct urls.
|
83
84
|
|
84
85
|
### Adding HATEOAS responses to existing routes
|
85
86
|
|
86
|
-
When creating a mobile application it's often useful to allow the app to request a non-html representation of a specific url.
|
87
|
+
When creating a mobile application it's often useful to allow the app to request a non-html representation of a specific url.
|
88
|
+
If you have an existing route:
|
87
89
|
|
88
90
|
```ruby
|
89
91
|
class BookController < ApplicationController
|
@@ -113,7 +115,9 @@ end
|
|
113
115
|
|
114
116
|
### Validations
|
115
117
|
|
116
|
-
Right now the serializer does not validate incoming or outgoing information.
|
118
|
+
Right now the serializer does not validate incoming or outgoing information.
|
119
|
+
This can cause issues when you accidentally emit non-conforming data that people start to depend on.
|
120
|
+
To make sure you don't do that you can specify a [Media Type validator](https://github.com/SleeplessByte/media-types-ruby):
|
117
121
|
|
118
122
|
```ruby
|
119
123
|
require 'media_types'
|
@@ -179,7 +183,8 @@ BookSerializer.serialize(book, BookValidator.version(2), context: nil)
|
|
179
183
|
|
180
184
|
### Links
|
181
185
|
|
182
|
-
When making [HATEOAS](https://docs.delftsolutions.nl/wiki/HATEOAS_API) compliant applications it's very useful to include `Link` headers in your response so clients can use a `HEAD` request instead of having to fetch the entire resource.
|
186
|
+
When making [HATEOAS](https://docs.delftsolutions.nl/wiki/HATEOAS_API) compliant applications it's very useful to include `Link` headers in your response so clients can use a `HEAD` request instead of having to fetch the entire resource.
|
187
|
+
Serializers have convenience methods to help with this:
|
183
188
|
|
184
189
|
```ruby
|
185
190
|
class BookSerializer < MediaTypes::Serialization::Base
|
@@ -218,7 +223,8 @@ There are convenience methods for serializing arrays of objects based on a templ
|
|
218
223
|
|
219
224
|
#### Indexes
|
220
225
|
|
221
|
-
An index is a collection of urls that point to members of the array.
|
226
|
+
An index is a collection of urls that point to members of the array.
|
227
|
+
The index method automatically generates it based on the self links defined in the default view of the same version.
|
222
228
|
|
223
229
|
```ruby
|
224
230
|
class BookSerializer < MediaTypes::Serialization::Base
|
@@ -260,7 +266,8 @@ BookSerializer.serialize([book], BookValidator.view(:index).version(3), context:
|
|
260
266
|
|
261
267
|
#### Collections
|
262
268
|
|
263
|
-
A collection inlines the member objects.
|
269
|
+
A collection inlines the member objects.
|
270
|
+
The collection method automatically generates it based on the default view of the same version.
|
264
271
|
|
265
272
|
```ruby
|
266
273
|
class BookSerializer < MediaTypes::Serialization::Base
|
@@ -329,6 +336,7 @@ class BookSerializer < MediaTypes::Serialization::Base
|
|
329
336
|
attribute :title, obj.title
|
330
337
|
attribute :description, obj.description if version >= 2
|
331
338
|
end
|
339
|
+
end
|
332
340
|
|
333
341
|
input version: 3
|
334
342
|
end
|
@@ -344,7 +352,7 @@ class BookController < ActionController::API
|
|
344
352
|
book = Book.new
|
345
353
|
book.title = 'Everything, abridged'
|
346
354
|
|
347
|
-
|
355
|
+
render_media serialize_media(book)
|
348
356
|
end
|
349
357
|
|
350
358
|
def create
|
@@ -390,14 +398,14 @@ class BookController < ActionController::API
|
|
390
398
|
book = Book.new
|
391
399
|
book.title = 'Everything, abridged'
|
392
400
|
|
393
|
-
|
401
|
+
render_media serialize_media(book)
|
394
402
|
end
|
395
403
|
|
396
404
|
def create
|
397
405
|
book = deserialize(request)
|
398
406
|
book.save!
|
399
407
|
|
400
|
-
|
408
|
+
render_media serialize_media(book)
|
401
409
|
end
|
402
410
|
end
|
403
411
|
```
|
@@ -406,7 +414,9 @@ If you don't want to apply any input validation or deserialization you can use t
|
|
406
414
|
|
407
415
|
### Raw output
|
408
416
|
|
409
|
-
Sometimes you need to output raw data.
|
417
|
+
Sometimes you need to output raw data.
|
418
|
+
This cannot be validated.
|
419
|
+
You do this as follows:
|
410
420
|
|
411
421
|
```ruby
|
412
422
|
class BookSerializer < MediaTypes::Serialization::Base
|
@@ -443,7 +453,8 @@ end
|
|
443
453
|
|
444
454
|
### Remapping media type identifiers
|
445
455
|
|
446
|
-
Sometimes you already have old clients using an `application/json` media type identifier when they do requests.
|
456
|
+
Sometimes you already have old clients using an `application/json` media type identifier when they do requests.
|
457
|
+
While this is not a good practise as this makes it hard to add new fields or remove old ones, this library has support for migrating away:
|
447
458
|
|
448
459
|
```ruby
|
449
460
|
class BookSerializer < MediaTypes::Serialization::Base
|
@@ -475,7 +486,8 @@ Validation will be done using the remapped validator. Aliasses map to version `n
|
|
475
486
|
|
476
487
|
### HTML
|
477
488
|
|
478
|
-
This library has a built in API viewer.
|
489
|
+
This library has a built in API viewer.
|
490
|
+
The viewer can be accessed by by appending a `?api_viewer=last` query parameter to the URL.
|
479
491
|
|
480
492
|
To enable the API viewer, use: `allow_api_viewer` in the controller.
|
481
493
|
|
@@ -493,7 +505,7 @@ class BookController < ActionController::API
|
|
493
505
|
book = Book.new
|
494
506
|
book.title = 'Everything, abridged'
|
495
507
|
|
496
|
-
|
508
|
+
render_media serialize_media(book)
|
497
509
|
end
|
498
510
|
|
499
511
|
def create
|
@@ -531,17 +543,18 @@ end
|
|
531
543
|
|
532
544
|
#### Errors
|
533
545
|
|
534
|
-
This library adds support for returning errors to clients using the [`application/problem+json`](https://tools.ietf.org/html/rfc7231) media type.
|
546
|
+
This library adds support for returning errors to clients using the [`application/problem+json`](https://tools.ietf.org/html/rfc7231) media type.
|
547
|
+
You can catch and transform application errors by adding an `output_error` call before `freeze_io!`:
|
535
548
|
|
536
549
|
```ruby
|
537
550
|
class BookController < ActionController::API
|
538
551
|
include MediaTypes::Serialization
|
539
552
|
|
540
|
-
output_error CanCan::AccessDenied do |
|
541
|
-
|
542
|
-
|
553
|
+
output_error CanCan::AccessDenied do |problem_output, error|
|
554
|
+
problem_output.title 'You do not have enough permissions to perform this action.', lang: 'en'
|
555
|
+
problem_output.title 'Je hebt geen toestemming om deze actie uit te voeren.', lang: 'nl-NL'
|
543
556
|
|
544
|
-
|
557
|
+
problem_output.status_code :forbidden
|
545
558
|
end
|
546
559
|
|
547
560
|
freeze_io!
|
@@ -550,12 +563,14 @@ class BookController < ActionController::API
|
|
550
563
|
end
|
551
564
|
```
|
552
565
|
|
553
|
-
The exception you specified will be rescued by the controller and will be displayed to the user along with a link to the shared wiki page for that error type. Feel free to add instructions there on how clients should solve this problem.
|
554
|
-
|
566
|
+
The exception you specified will be rescued by the controller and will be displayed to the user along with a link to the shared wiki page for that error type. Feel free to add instructions there on how clients should solve this problem.
|
567
|
+
You can find more information at: [https://docs.delftsolutions.nl/wiki/Error](https://docs.delftsolutions.nl/wiki/Error)
|
568
|
+
If you want to override this url you can use the `problem_output.url(href)` function.
|
555
569
|
|
556
|
-
By default the `message` property of the error is used to fill the `details` field.
|
570
|
+
By default the `message` property of the error is used to fill the `details` field.
|
571
|
+
You can override this by using the `problem_output.override_details(description, lang:)` function.
|
557
572
|
|
558
|
-
Custom attributes can be added using the `
|
573
|
+
Custom attributes can be added using the `problem_output.attribute(name, value)` function.
|
559
574
|
|
560
575
|
### Related
|
561
576
|
|
@@ -563,7 +578,7 @@ Custom attributes can be added using the `p.attribute(name, value)` function.
|
|
563
578
|
|
564
579
|
## API
|
565
580
|
|
566
|
-
### Serializer definition
|
581
|
+
### Serializer class definition
|
567
582
|
|
568
583
|
These methods become available during class definition if you inherit from `MediaTypes::Serialization::Base`.
|
569
584
|
|
@@ -581,65 +596,95 @@ Either validator or unvalidated must be used while defining a serializer.
|
|
581
596
|
|
582
597
|
#### `output( view:, version:, versions: ) do |obj, version, context|`
|
583
598
|
|
584
|
-
Defines a serialization block. Either version or versions can be set.
|
599
|
+
Defines a serialization block. Either version or versions can be set.
|
600
|
+
`nil` is allowed for unversioned.
|
601
|
+
View should be a symbol or unset.
|
585
602
|
|
586
|
-
Obj is the object to be serialized, version is the negotiated version and context is the context passed in from the serialize function.
|
603
|
+
Obj is the object to be serialized, version is the negotiated version and context is the context passed in from the serialize function.
|
604
|
+
When using the controller integration, context is the current controller.
|
587
605
|
|
588
606
|
The block should return an object to convert into JSON.
|
589
607
|
|
590
|
-
#### `output_raw( view:, version:, versions: ) do |obj, version, context|`
|
608
|
+
#### `output_raw( view:, version:, versions:, suffix: ) do |obj, version, context|`
|
591
609
|
|
592
|
-
This has the same behavior as `output` but should return a string instead of an object.
|
610
|
+
This has the same behavior as `output` but should return a string instead of an object.
|
611
|
+
Output is not validated.
|
612
|
+
By default, `input_raw` is expected to _not_ be JSON.
|
613
|
+
Override `suffix` with `:json` if it _is_ JSON.
|
593
614
|
|
594
|
-
#### `output_alias( media_type_identifier, view:, hide_variant: false )`
|
615
|
+
#### `output_alias( media_type_identifier, view:, hide_variant: false, suffix: '~' )`
|
595
616
|
|
596
|
-
Defines a legacy mapping. This will make the deserializer parse the media type `media_type_identifier` as if it was version `nil` of the specified view.
|
617
|
+
Defines a legacy mapping. This will make the deserializer parse the media type `media_type_identifier` as if it was version `nil` of the specified view.
|
618
|
+
If `view` is undefined it will use the output serializer without a view defined.
|
619
|
+
By default, suffix is `:json` if `media_type_identifier` is a JSON type.
|
597
620
|
|
598
|
-
Response will have a content type equal to `[media_type_identifier]; variant=[mapped_media_type_identifier]`.
|
621
|
+
Response will have a content type equal to `[media_type_identifier]; variant=[mapped_media_type_identifier]`.
|
622
|
+
If `hide_variant:` is true, the content type emitted will only be `[media_type_identifier]`.
|
623
|
+
|
624
|
+
> You cannot alias a _versioned_ media type, otherwise it would be easy to later break the definition by changing the version it aliases.
|
599
625
|
|
600
|
-
#### `output_alias_optional( media_type_identifier, view:, hide_variant: false )`
|
626
|
+
#### `output_alias_optional( media_type_identifier, view:, hide_variant: false, suffix: '~' )`
|
601
627
|
|
602
|
-
Has the same behavior as `output_alias` but can be used by multiple serializers.
|
628
|
+
Has the same behavior as `output_alias` but can be used by multiple serializers.
|
629
|
+
The serializer that is loaded last in the controller 'wins' control over this media type identifier.
|
630
|
+
If any of the serializers have an `output_alias` defined with the same media type identifier that one will win instead.
|
631
|
+
By default, suffix is `:json` if `media_type_identifier` is a JSON type.
|
603
632
|
|
604
633
|
Response will have a content type equal to `[media_type_identifier]; variant=[mapped_media_type_identifier]`. If `hide_variant:` is true, the content type emitted will only be `[media_type_identifier]`.
|
605
634
|
|
606
635
|
#### `input( view:, version:, versions: ) do |obj, version, context|`
|
607
636
|
|
608
|
-
Defines a deserialization block. Either version or versions can be set.
|
637
|
+
Defines a deserialization block. Either version or versions can be set.
|
638
|
+
View should be a symbol or unset.
|
609
639
|
|
610
|
-
Obj is the object to be serialized, version is the negotiated version and context is the context passed in from the serialize function.
|
640
|
+
Obj is the object to be serialized, version is the negotiated version and context is the context passed in from the serialize function.
|
641
|
+
When using the controller integration, context is the current controller.
|
611
642
|
|
612
|
-
The block should return the internal representation of the object.
|
643
|
+
The block should return the internal representation of the object.
|
644
|
+
Best practise is to make sure not to change state in this function but to leave that up to the controller.
|
613
645
|
|
614
|
-
#### `input_raw( view:, version:, versions: ) do |bytes, version, context|`
|
646
|
+
#### `input_raw( view:, version:, versions:, suffix: nil ) do |bytes, version, context|`
|
615
647
|
|
616
|
-
This has the same behavior as `input` but takes in raw data.
|
648
|
+
This has the same behavior as `input` but takes in raw data.
|
649
|
+
Input is not validated.
|
650
|
+
By default, `input_raw` is expected to _not_ be JSON.
|
651
|
+
Override `suffix` with `:json` if it _is_ JSON.
|
617
652
|
|
618
|
-
#### `input_alias( media_type_identifier, view: )`
|
653
|
+
#### `input_alias( media_type_identifier, view:, suffix: '~' )`
|
619
654
|
|
620
|
-
Defines a legacy mapping.
|
655
|
+
Defines a legacy mapping.
|
656
|
+
This will make the serializer parse the media type `media_type_identifier` as if it was version `nil` of the specified view.
|
657
|
+
If view is undefined it will use the input serializer without a view defined.
|
658
|
+
By default, suffix is `:json` if `media_type_identifier` is a JSON type.
|
621
659
|
|
622
|
-
|
660
|
+
> You cannot alias a _versioned_ media type, otherwise it would be easy to later break the definition by changing the version it aliases.
|
623
661
|
|
624
|
-
|
662
|
+
#### `input_alias_optional( media_type_identifier, view:, suffix: '~' )`
|
663
|
+
|
664
|
+
Has the same behavior as `input_alias` but can be used by multiple serializers.
|
665
|
+
The serializer that is loaded last in the controller 'wins' control over this media type identifier.
|
666
|
+
If any of the serializers have an `input_alias` defined with the same media type identifier that one will win instead.
|
667
|
+
By default, suffix is `:json` if `media_type_identifier` is a JSON type.
|
625
668
|
|
626
669
|
#### `disable_wildcards`
|
627
670
|
|
628
671
|
Disables registering wildcard media types.
|
629
672
|
|
630
|
-
### Serializer definition
|
673
|
+
### Serializer output definition
|
631
674
|
|
632
675
|
The following methods are available within an `output ... do` block.
|
633
676
|
|
634
677
|
#### `attribute( key, value = {} ) do`
|
635
678
|
|
636
|
-
Sets a value for the given key.
|
679
|
+
Sets a value for the given key.
|
680
|
+
If a block is given, any `attribute`, `link`, `collection` and `index` statements are run in context of `value`.
|
637
681
|
|
638
682
|
Returns the built up context so far.
|
639
683
|
|
640
684
|
#### `link( rel, href:, emit_header: true, **attributes )`
|
641
685
|
|
642
|
-
Adds a `_link` block to the current context. Also adds the specified link to the HTTP Link header.
|
686
|
+
Adds a `_link` block to the current context. Also adds the specified link to the HTTP Link header.
|
687
|
+
`attributes` allows passing in custom attributes.
|
643
688
|
|
644
689
|
If `emit_header` is `true` the link will also be emitted as a http header.
|
645
690
|
|
@@ -647,12 +692,16 @@ Returns the built up context so far.
|
|
647
692
|
|
648
693
|
#### `index( array, serializer, version:, view: nil )`
|
649
694
|
|
695
|
+
> Not the same as a validator `collection`.
|
696
|
+
|
650
697
|
Adds an `_index` block to the current context. Uses the self links of the specified view to construct an index of urls to the child objects.
|
651
698
|
|
652
699
|
Returns the built up context so far.
|
653
700
|
|
654
701
|
#### `collection( array, serializer, version:, view: nil )`
|
655
702
|
|
703
|
+
> Not the same as a validator `collection`.
|
704
|
+
|
656
705
|
Adds an `_embedded` block to the current context. Uses the specified serializer to embed the child objects.
|
657
706
|
Optionally a block can be used to modify the output from the child serializer.
|
658
707
|
|
@@ -660,7 +709,9 @@ Returns the built up context so far.
|
|
660
709
|
|
661
710
|
#### `hidden do`
|
662
711
|
|
663
|
-
Sometimes you want to add links without actually modifying the object.
|
712
|
+
Sometimes you want to add links without actually modifying the object.
|
713
|
+
Calls to `attribute`, `link`, `index`, `collection` made inside this block won't modify the context.
|
714
|
+
Any calls to link will only set the HTTP Link header.
|
664
715
|
|
665
716
|
Returns the unmodified context.
|
666
717
|
|
@@ -674,9 +725,25 @@ Returns the built up context so far.
|
|
674
725
|
|
675
726
|
Runs a block in a new context and returns the result
|
676
727
|
|
728
|
+
> Most common use-case is emitting from an enumerable.
|
729
|
+
>
|
730
|
+
> ```ruby
|
731
|
+
> results = [item, item, item].map do |current_item|
|
732
|
+
> object do
|
733
|
+
> attribute :foo, current_item.bar
|
734
|
+
> end
|
735
|
+
> end
|
736
|
+
>
|
737
|
+
> attribute :items, results
|
738
|
+
> ```
|
739
|
+
|
677
740
|
#### `render_view( view, context:, **args)`
|
678
741
|
|
679
|
-
Can be used to render a view.
|
742
|
+
Can be used to render a view.
|
743
|
+
You can set local variables in the view by assigning a hash to the `assigns:` parameter.
|
744
|
+
Returns a `string`
|
745
|
+
|
746
|
+
> When possible, prefer `output_raw` with `context.class.render(params)`
|
680
747
|
|
681
748
|
### Controller definition
|
682
749
|
|
@@ -684,7 +751,8 @@ These functions are available during the controller definition if you add `inclu
|
|
684
751
|
|
685
752
|
#### `allow_output_serializer( serializer, views: nil, **filters )`
|
686
753
|
|
687
|
-
Configure the controller to allow the client to request responses emitted by the specified serializer.
|
754
|
+
Configure the controller to allow the client to request responses emitted by the specified serializer.
|
755
|
+
Optionally allows you to specify which views to allow by passing an array in the views parameter.
|
688
756
|
|
689
757
|
Accepts the same filters as `before_action`.
|
690
758
|
|
@@ -692,9 +760,11 @@ Accepts the same filters as `before_action`.
|
|
692
760
|
|
693
761
|
Allows falling back to the default Rails view rendering when the client asks for the media type in the `as:` parameter or `text/html` if `as:` is unset.
|
694
762
|
|
695
|
-
The `Content-Type` of the response will be `text/html` if the `as:` parameter is unset.
|
763
|
+
The `Content-Type` of the response will be `text/html` if the `as:` parameter is unset.
|
764
|
+
If the `as:` parameter is set, it will include it in the variant parameter: `text/html; variant=application/vnd.xpbytes.borderless`.
|
696
765
|
|
697
|
-
Accepts the same filters as `before_action`.
|
766
|
+
Accepts the same filters as `before_action`.
|
767
|
+
You can set the template to use using the `view:` parameter.
|
698
768
|
|
699
769
|
#### `allow_output_docs( description, **filters )`
|
700
770
|
|
@@ -704,7 +774,8 @@ Accepts the same filters as `before_action`.
|
|
704
774
|
|
705
775
|
#### `allow_input_serializer( serializer, views: nil, **filters )`
|
706
776
|
|
707
|
-
Configure the controller to allow the client to send bodies with a `Content-Type` that can be deserialized using the specified serializer.
|
777
|
+
Configure the controller to allow the client to send bodies with a `Content-Type` that can be deserialized using the specified serializer.
|
778
|
+
Optionally allows you to specify which views to allow by passing an array in the views parameter.
|
708
779
|
|
709
780
|
Accepts the same filters as `before_action`.
|
710
781
|
|
@@ -738,7 +809,8 @@ Enables rendering the api viewer when adding the `api_viewer=last` query paramet
|
|
738
809
|
|
739
810
|
#### `freeze_io!(**filter_opts)`
|
740
811
|
|
741
|
-
Registers serialization and deserialization in the controller.
|
812
|
+
Registers serialization and deserialization in the controller.
|
813
|
+
This function must be called before using the controller.
|
742
814
|
|
743
815
|
### Controller usage
|
744
816
|
|
@@ -746,7 +818,8 @@ These functions are available during method execution in the controller.
|
|
746
818
|
|
747
819
|
#### `render_media( obj, serializers: nil, not_acceptable_serializer: nil, **options ) do`
|
748
820
|
|
749
|
-
Serializes an object and renders it using the appropriate content type.
|
821
|
+
Serializes an object and renders it using the appropriate content type.
|
822
|
+
Options are passed through to the controller `render` function. Allows you to specify different objects to different serializers using a block:
|
750
823
|
|
751
824
|
```ruby
|
752
825
|
render_media do
|
@@ -757,13 +830,15 @@ render_media do
|
|
757
830
|
end
|
758
831
|
```
|
759
832
|
|
760
|
-
Warning
|
833
|
+
**Warning**: this block can be called multiple times when used together with recursive serializers like the API viewer.
|
834
|
+
Try to _avoid changing state_ in this block.
|
761
835
|
|
762
836
|
If you want to render with different serializers than defined in the controller you can pass an array of serializers in the `serializers` property.
|
763
837
|
|
764
838
|
If you want to override the serializer that is used to render the response when no acceptable Content-Type could be negotiated you can pass the desired serializer in the `not_acceptable_serializer` property.
|
765
839
|
|
766
|
-
This method throws a `MediaTypes::Serialization::OutputValidationFailedError` error if the output does not conform to the format defined by the configured validator.
|
840
|
+
This method throws a `MediaTypes::Serialization::OutputValidationFailedError` error if the output does not conform to the format defined by the configured validator.
|
841
|
+
Best practise is to return a 500 error to the client.
|
767
842
|
|
768
843
|
If no acceptable Content-Type could be negotiated the response will be rendered using the serialized defined by the class `not_acceptable_serializer` function or by the `not_acceptable_serializer` property.
|
769
844
|
|
@@ -805,12 +880,11 @@ HERE
|
|
805
880
|
|
806
881
|
## Development
|
807
882
|
|
808
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
809
|
-
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
883
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
884
|
+
Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
810
885
|
|
811
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
812
|
-
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
813
|
-
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
886
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
887
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
814
888
|
|
815
889
|
## Contributing
|
816
890
|
|
@@ -184,7 +184,7 @@ module MediaTypes
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
def allow_output_html(as: nil, view: nil, layout: nil, **filter_opts)
|
187
|
+
def allow_output_html(as: nil, view: nil, layout: nil, formats: [:html], variants: nil, **filter_opts)
|
188
188
|
before_action(**filter_opts) do
|
189
189
|
raise SerializersAlreadyFrozenError if defined? @serialization_frozen
|
190
190
|
|
@@ -197,19 +197,13 @@ module MediaTypes
|
|
197
197
|
validator = FakeValidator.new(as.nil? ? 'text/html' : as)
|
198
198
|
|
199
199
|
block = lambda { |_, _, controller|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
if view.nil?
|
208
|
-
controller.render_to_string(layout: layout)
|
209
|
-
else
|
210
|
-
controller.render_to_string(template: view, layout: layout)
|
211
|
-
end
|
212
|
-
end
|
200
|
+
options = {}
|
201
|
+
options[:layout] = layout unless layout.nil?
|
202
|
+
options[:template] = view unless view.nil?
|
203
|
+
options[:formats] = formats unless formats.nil?
|
204
|
+
options[:variants] = variants unless variants.nil?
|
205
|
+
|
206
|
+
controller.render_to_string(**options)
|
213
207
|
}
|
214
208
|
|
215
209
|
html_registration.register_block(nil, validator, nil, block, true, wildcards: true)
|
@@ -342,11 +336,6 @@ module MediaTypes
|
|
342
336
|
end
|
343
337
|
# rubocop:enable Metrics/BlockLength
|
344
338
|
|
345
|
-
included do
|
346
|
-
protected
|
347
|
-
|
348
|
-
end
|
349
|
-
|
350
339
|
protected
|
351
340
|
|
352
341
|
def serialize(victim, media_type, serializer: Object.new, links: [], vary: ['Accept'])
|
@@ -356,7 +345,10 @@ module MediaTypes
|
|
356
345
|
|
357
346
|
MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED = ::Object.new
|
358
347
|
|
359
|
-
def render_media(obj = MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED,
|
348
|
+
def render_media(obj = MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED, **options, &block)
|
349
|
+
serializers = options.delete(:serializers)
|
350
|
+
not_acceptable_serializer = options.delete(:not_acceptable_serializer)
|
351
|
+
|
360
352
|
if obj == MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED && options.keys.any? && !block
|
361
353
|
# options is too greedy :(
|
362
354
|
obj = options
|
@@ -366,6 +358,7 @@ module MediaTypes
|
|
366
358
|
if obj == MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED && block.nil?
|
367
359
|
raise 'render_media was called without an object. Please provide one or supply a block to match the serializer.'
|
368
360
|
end
|
361
|
+
|
369
362
|
obj = nil if obj == MEDIA_TYPES_SERIALIZATION_OBJ_IS_UNDEFINED
|
370
363
|
|
371
364
|
raise SerializersNotFrozenError unless defined? @serialization_frozen
|
@@ -395,10 +388,17 @@ module MediaTypes
|
|
395
388
|
selector.instance_exec(&block)
|
396
389
|
|
397
390
|
raise UnmatchedSerializerError, serializer unless selector.matched
|
391
|
+
|
398
392
|
obj = selector.value
|
399
393
|
end
|
400
394
|
|
401
|
-
serialization_render_resolved(
|
395
|
+
serialization_render_resolved(
|
396
|
+
obj: obj,
|
397
|
+
serializer: serializer,
|
398
|
+
identifier: identifier,
|
399
|
+
registrations: registration,
|
400
|
+
options: options
|
401
|
+
)
|
402
402
|
end
|
403
403
|
|
404
404
|
def deserialize(request)
|
@@ -417,6 +417,7 @@ module MediaTypes
|
|
417
417
|
raise SerializersNotFrozenError unless defined?(@serialization_frozen)
|
418
418
|
raise NoInputReceivedError if request.content_type.blank?
|
419
419
|
raise InputNotAcceptableError unless @serialization_input_registrations.has? request.content_type
|
420
|
+
|
420
421
|
@serialization_input_registrations.call(@serialization_decoded_input, request.content_type, self)
|
421
422
|
end
|
422
423
|
|
@@ -427,6 +428,7 @@ module MediaTypes
|
|
427
428
|
registration = registration.registrations[identifier]
|
428
429
|
|
429
430
|
raise 'Assertion failed, inconsistent answer from resolve_media_type' if registration.nil?
|
431
|
+
|
430
432
|
registration.serializer
|
431
433
|
end
|
432
434
|
|
@@ -434,8 +436,12 @@ module MediaTypes
|
|
434
436
|
|
435
437
|
def resolve_media_type(request, registration, allow_last: true)
|
436
438
|
if defined? @serialization_override_accept
|
437
|
-
|
439
|
+
if allow_last && @serialization_override_accept == 'last'
|
440
|
+
@serialization_override_accept = registration.registrations.keys.last
|
441
|
+
end
|
442
|
+
|
438
443
|
return nil unless registration.has? @serialization_override_accept
|
444
|
+
|
439
445
|
return @serialization_override_accept
|
440
446
|
end
|
441
447
|
|
@@ -483,7 +489,10 @@ module MediaTypes
|
|
483
489
|
input_is_allowed = @serialization_input_registrations.has? request.content_type unless request.content_type.blank?
|
484
490
|
|
485
491
|
unless input_is_allowed || all_allowed
|
486
|
-
serializers = @serialization_unsupported_media_type_serializer || [
|
492
|
+
serializers = @serialization_unsupported_media_type_serializer || [
|
493
|
+
MediaTypes::Serialization::Serializers::ProblemSerializer,
|
494
|
+
MediaTypes::Serialization::Serializers::FallbackUnsupportedMediaTypeSerializer
|
495
|
+
]
|
487
496
|
registrations = SerializationRegistration.new(:output)
|
488
497
|
serializers.each do |s|
|
489
498
|
registrations = registrations.merge(s.outputs_for(views: [nil, :html]))
|
@@ -511,7 +520,10 @@ module MediaTypes
|
|
511
520
|
input_data = request.body.read
|
512
521
|
@serialization_decoded_input = @serialization_input_registrations.decode(input_data, request.content_type, self)
|
513
522
|
rescue InputValidationFailedError => e
|
514
|
-
serializers = @serialization_input_validation_failed_serializer || [
|
523
|
+
serializers = @serialization_input_validation_failed_serializer || [
|
524
|
+
MediaTypes::Serialization::Serializers::ProblemSerializer,
|
525
|
+
MediaTypes::Serialization::Serializers::InputValidationErrorSerializer
|
526
|
+
]
|
515
527
|
registrations = SerializationRegistration.new(:output)
|
516
528
|
serializers.each do |s|
|
517
529
|
registrations = registrations.merge(s.outputs_for(views: [nil, :html]))
|
@@ -557,7 +569,13 @@ module MediaTypes
|
|
557
569
|
actions: @serialization_available_serializers,
|
558
570
|
}
|
559
571
|
|
560
|
-
serialization_render_resolved
|
572
|
+
serialization_render_resolved(
|
573
|
+
obj: input,
|
574
|
+
serializer: description_serializer,
|
575
|
+
identifier: endpoint_matched_identifier,
|
576
|
+
registrations: @serialization_output_registrations,
|
577
|
+
options: {}
|
578
|
+
)
|
561
579
|
return
|
562
580
|
end
|
563
581
|
|
@@ -603,7 +621,7 @@ module MediaTypes
|
|
603
621
|
output: result,
|
604
622
|
links: links,
|
605
623
|
}
|
606
|
-
wrapped = @serialization_wrapping_renderer.serialize input, '*/*', self
|
624
|
+
wrapped = @serialization_wrapping_renderer.serialize input, '*/*', context: self
|
607
625
|
render body: wrapped
|
608
626
|
|
609
627
|
response.content_type = 'text/html'
|
@@ -44,35 +44,76 @@ module MediaTypes
|
|
44
44
|
validator = serializer_validator.view(view).version(v)
|
45
45
|
validator.override_suffix(:json) unless serializer_validated
|
46
46
|
|
47
|
-
serializer_output_registration.register_block(
|
47
|
+
serializer_output_registration.register_block(
|
48
|
+
self,
|
49
|
+
validator,
|
50
|
+
v,
|
51
|
+
block,
|
52
|
+
false,
|
53
|
+
wildcards:
|
54
|
+
!serializer_disable_wildcards
|
55
|
+
)
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
51
|
-
def output_raw(view: nil, version: nil, versions: nil, &block)
|
59
|
+
def output_raw(view: nil, version: nil, versions: nil, suffix: nil, &block)
|
52
60
|
versions = [version] if versions.nil?
|
53
61
|
raise VersionsNotAnArrayError unless versions.is_a? Array
|
54
62
|
|
55
63
|
raise ValidatorNotSpecifiedError, :output if serializer_validator.nil?
|
56
64
|
|
57
65
|
versions.each do |v|
|
58
|
-
validator = serializer_validator.view(view)
|
59
|
-
|
60
|
-
|
66
|
+
validator = serializer_validator.view(view)
|
67
|
+
.version(v)
|
68
|
+
.override_suffix(suffix)
|
69
|
+
|
70
|
+
serializer_output_registration.register_block(
|
71
|
+
self,
|
72
|
+
validator,
|
73
|
+
v,
|
74
|
+
block,
|
75
|
+
true,
|
76
|
+
wildcards: !serializer_disable_wildcards
|
77
|
+
)
|
61
78
|
end
|
62
79
|
end
|
63
80
|
|
64
|
-
def output_alias(
|
65
|
-
|
81
|
+
def output_alias(
|
82
|
+
media_type_identifier,
|
83
|
+
view: nil,
|
84
|
+
suffix: media_type_identifier == 'application/json' || media_type_identifier.end_with?('+json') ? :json : nil,
|
85
|
+
hide_variant: false
|
86
|
+
)
|
87
|
+
validator = serializer_validator.view(view).override_suffix(suffix)
|
66
88
|
victim_identifier = validator.identifier
|
67
89
|
|
68
|
-
serializer_output_registration.register_alias(
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
90
|
+
serializer_output_registration.register_alias(
|
91
|
+
self,
|
92
|
+
media_type_identifier,
|
93
|
+
victim_identifier,
|
94
|
+
false,
|
95
|
+
hide_variant,
|
96
|
+
wildcards: !serializer_disable_wildcards
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def output_alias_optional(
|
101
|
+
media_type_identifier,
|
102
|
+
view: nil,
|
103
|
+
suffix: media_type_identifier == 'application/json' || media_type_identifier.end_with?('+json') ? :json : nil,
|
104
|
+
hide_variant: false
|
105
|
+
)
|
106
|
+
validator = serializer_validator.view(view).override_suffix(suffix)
|
73
107
|
victim_identifier = validator.identifier
|
74
108
|
|
75
|
-
serializer_output_registration.register_alias(
|
109
|
+
serializer_output_registration.register_alias(
|
110
|
+
self,
|
111
|
+
media_type_identifier,
|
112
|
+
victim_identifier,
|
113
|
+
true,
|
114
|
+
hide_variant,
|
115
|
+
wildcards: !serializer_disable_wildcards
|
116
|
+
)
|
76
117
|
end
|
77
118
|
|
78
119
|
def input(view: nil, version: nil, versions: nil, &block)
|
@@ -89,39 +130,61 @@ module MediaTypes
|
|
89
130
|
end
|
90
131
|
end
|
91
132
|
|
92
|
-
def input_raw(view: nil, version: nil, versions: nil, &block)
|
133
|
+
def input_raw(view: nil, version: nil, versions: nil, suffix: nil, &block)
|
93
134
|
versions = [version] if versions.nil?
|
94
135
|
raise VersionsNotAnArrayError unless versions.is_a? Array
|
95
136
|
|
96
137
|
raise ValidatorNotSpecifiedError, :input if serializer_validator.nil?
|
97
138
|
|
98
139
|
versions.each do |v|
|
99
|
-
validator = serializer_validator.view(view).version(v)
|
140
|
+
validator = serializer_validator.view(view).version(v).override_suffix(suffix)
|
100
141
|
|
101
142
|
serializer_input_registration.register_block(self, validator, v, block, true)
|
102
143
|
end
|
103
144
|
end
|
104
145
|
|
105
|
-
def input_alias(
|
106
|
-
|
146
|
+
def input_alias(
|
147
|
+
media_type_identifier,
|
148
|
+
view: nil,
|
149
|
+
suffix: media_type_identifier == 'application/json' || media_type_identifier.end_with?('+json') ? :json : nil
|
150
|
+
)
|
151
|
+
validator = serializer_validator.view(view).override_suffix(suffix)
|
107
152
|
victim_identifier = validator.identifier
|
108
153
|
|
109
|
-
serializer_input_registration.register_alias(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
154
|
+
serializer_input_registration.register_alias(
|
155
|
+
self,
|
156
|
+
media_type_identifier,
|
157
|
+
victim_identifier,
|
158
|
+
false,
|
159
|
+
true,
|
160
|
+
wildcards: false
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
def input_alias_optional(
|
165
|
+
media_type_identifier,
|
166
|
+
view: nil,
|
167
|
+
suffix: media_type_identifier == 'application/json' || media_type_identifier.end_with?('+json') ? :json : nil
|
168
|
+
)
|
169
|
+
validator = serializer_validator.view(view).override_suffix(suffix)
|
114
170
|
victim_identifier = validator.identifier
|
115
171
|
|
116
|
-
serializer_input_registration.register_alias(
|
172
|
+
serializer_input_registration.register_alias(
|
173
|
+
self,
|
174
|
+
media_type_identifier,
|
175
|
+
victim_identifier,
|
176
|
+
true,
|
177
|
+
true,
|
178
|
+
wildcards: false
|
179
|
+
)
|
117
180
|
end
|
118
181
|
|
119
|
-
def serialize(victim, media_type_identifier, context
|
182
|
+
def serialize(victim, media_type_identifier, context:, dsl: nil, raw: nil)
|
120
183
|
dsl ||= SerializationDSL.new(self, context: context)
|
121
184
|
serializer_output_registration.call(victim, media_type_identifier.to_s, context, dsl: dsl, raw: raw)
|
122
185
|
end
|
123
186
|
|
124
|
-
def deserialize(victim, media_type_identifier, context)
|
187
|
+
def deserialize(victim, media_type_identifier, context:)
|
125
188
|
serializer_input_registration.call(victim, media_type_identifier, context)
|
126
189
|
end
|
127
190
|
|
@@ -135,6 +198,8 @@ module MediaTypes
|
|
135
198
|
end
|
136
199
|
|
137
200
|
def self.inherited(subclass)
|
201
|
+
super
|
202
|
+
|
138
203
|
subclass.extend(ClassMethods)
|
139
204
|
subclass.instance_eval do
|
140
205
|
class << self
|
@@ -56,7 +56,7 @@ module MediaTypes
|
|
56
56
|
array.each do |e|
|
57
57
|
child_links = []
|
58
58
|
context = SerializationDSL.new(__getobj__, child_links, context: @serialization_context)
|
59
|
-
serializer.serialize(e, identifier, @serialization_context, dsl: context)
|
59
|
+
serializer.serialize(e, identifier, context: @serialization_context, dsl: context)
|
60
60
|
|
61
61
|
self_links = child_links.select { |l| l[:rel] == :self }
|
62
62
|
raise NoSelfLinkProvidedError, identifier unless self_links.any?
|
@@ -79,7 +79,7 @@ module MediaTypes
|
|
79
79
|
|
80
80
|
array.each do |e|
|
81
81
|
context = SerializationDSL.new(__getobj__, [], @serialization_vary, context: @serialization_context)
|
82
|
-
result = serializer.serialize(e, identifier, @serialization_context, dsl: context, raw: true)
|
82
|
+
result = serializer.serialize(e, identifier, context: @serialization_context, dsl: context, raw: true)
|
83
83
|
|
84
84
|
result = block.call(result) unless block.nil?
|
85
85
|
|
@@ -105,7 +105,7 @@ module MediaTypes
|
|
105
105
|
def emit
|
106
106
|
serialization_dsl_result
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def object(&block)
|
110
110
|
context = SerializationDSL.new(__getobj__, @serialization_links, @serialization_vary, context: @serialization_context)
|
111
111
|
context.instance_exec(&block)
|
@@ -36,7 +36,7 @@ module MediaTypes
|
|
36
36
|
|
37
37
|
unless registrations.key? target_identifier
|
38
38
|
potential_match = registrations.keys.find do |k|
|
39
|
-
k.
|
39
|
+
k.start_with? target_identifier
|
40
40
|
end
|
41
41
|
raise VersionedAliasDefinitionError.new(target_identifier, inout, potential_match) unless potential_match.nil?
|
42
42
|
raise UnbackedAliasDefinitionError.new(target_identifier, inout)
|
@@ -152,7 +152,7 @@ module MediaTypes
|
|
152
152
|
self.raw = raw
|
153
153
|
super(serializer, inout, validator, display_identifier)
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
def merge(other)
|
157
157
|
return nil unless other.is_a?(SerializationAliasRegistration)
|
158
158
|
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
|
38
38
|
spec.add_dependency 'actionpack', '>= 4.0.0'
|
39
39
|
spec.add_dependency 'activesupport', '>= 4.0.0'
|
40
|
-
spec.add_dependency 'media_types', '>= 2.
|
40
|
+
spec.add_dependency 'media_types', '>= 2.1.0', '< 3.0.0'
|
41
41
|
|
42
42
|
spec.add_development_dependency 'awesome_print'
|
43
43
|
spec.add_development_dependency 'bundler'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: media_types-serialization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derk-Jan Karrenbeld
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 2.
|
48
|
+
version: 2.1.0
|
49
49
|
- - "<"
|
50
50
|
- !ruby/object:Gem::Version
|
51
51
|
version: 3.0.0
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
requirements:
|
56
56
|
- - ">="
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: 2.
|
58
|
+
version: 2.1.0
|
59
59
|
- - "<"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 3.0.0
|