jsonapi-resources 0.4.2 → 0.4.3
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/Gemfile +2 -2
- data/README.md +103 -71
- data/Rakefile +2 -2
- data/jsonapi-resources.gemspec +2 -2
- data/lib/jsonapi-resources.rb +0 -1
- data/lib/jsonapi/active_record_operations_processor.rb +10 -2
- data/lib/jsonapi/acts_as_resource_controller.rb +26 -24
- data/lib/jsonapi/association.rb +50 -15
- data/lib/jsonapi/callbacks.rb +1 -2
- data/lib/jsonapi/configuration.rb +8 -24
- data/lib/jsonapi/error.rb +1 -2
- data/lib/jsonapi/error_codes.rb +3 -1
- data/lib/jsonapi/exceptions.rb +59 -47
- data/lib/jsonapi/include_directives.rb +11 -11
- data/lib/jsonapi/mime_types.rb +2 -2
- data/lib/jsonapi/operation.rb +28 -11
- data/lib/jsonapi/operations_processor.rb +16 -5
- data/lib/jsonapi/paginator.rb +19 -19
- data/lib/jsonapi/request.rb +175 -196
- data/lib/jsonapi/resource.rb +158 -105
- data/lib/jsonapi/resource_serializer.rb +37 -26
- data/lib/jsonapi/resources/version.rb +2 -2
- data/lib/jsonapi/response_document.rb +5 -4
- data/lib/jsonapi/routing_ext.rb +24 -19
- data/test/controllers/controller_test.rb +261 -31
- data/test/fixtures/active_record.rb +206 -8
- data/test/fixtures/book_comments.yml +2 -1
- data/test/fixtures/books.yml +1 -0
- data/test/fixtures/documents.yml +3 -0
- data/test/fixtures/people.yml +8 -1
- data/test/fixtures/pictures.yml +15 -0
- data/test/fixtures/products.yml +3 -0
- data/test/fixtures/vehicles.yml +8 -0
- data/test/helpers/{hash_helpers.rb → assertions.rb} +6 -1
- data/test/integration/requests/request_test.rb +14 -3
- data/test/integration/routes/routes_test.rb +47 -0
- data/test/test_helper.rb +27 -4
- data/test/unit/serializer/include_directives_test.rb +5 -0
- data/test/unit/serializer/polymorphic_serializer_test.rb +384 -0
- data/test/unit/serializer/serializer_test.rb +19 -1
- metadata +14 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 797927f93aedcb2dab47c655c02b3b0fc585ae3a
|
4
|
+
data.tar.gz: 679a57fb31f8a64b19735130d70bd79eef9b46ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39a597f4b31a1273f4a7a71bf3b46ea0a19251b235a2fb8212c3452d959c6b01094a33420bad1fc7ac69d1c082d8193cb99d7c73e5f541c747c60d3503de1190
|
7
|
+
data.tar.gz: 819a12d466c075c127b9a9c6863b675fd3dc28a21f011022132c460badeb8e102745aacfb9cc4c6cab4c60d4f69d41f9b22fbbe8c1804ad4b92c2c0a43006a54
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# JSONAPI::Resources [](http://travis-ci.org/cerebris/jsonapi-resources)
|
2
2
|
|
3
|
-
`JSONAPI::Resources`, or "JR", provides a framework for developing a server that complies with the
|
3
|
+
`JSONAPI::Resources`, or "JR", provides a framework for developing a server that complies with the
|
4
4
|
[JSON API](http://jsonapi.org/) specification.
|
5
5
|
|
6
|
-
Like JSON API itself, JR's design is focused on the resources served by an API. JR needs little more than a definition
|
6
|
+
Like JSON API itself, JR's design is focused on the resources served by an API. JR needs little more than a definition
|
7
7
|
of your resources, including their attributes and relationships, to make your server compliant with JSON API.
|
8
8
|
|
9
|
-
JR is designed to work with Rails 4.0+, and provides custom routes, controllers, and serializers. JR's resources may be
|
9
|
+
JR is designed to work with Rails 4.0+, and provides custom routes, controllers, and serializers. JR's resources may be
|
10
10
|
backed by ActiveRecord models or by custom objects.
|
11
11
|
|
12
12
|
## Demo App
|
@@ -15,7 +15,7 @@ We have a simple demo app, called [Peeps](https://github.com/cerebris/peeps), av
|
|
15
15
|
|
16
16
|
## Client Libraries
|
17
17
|
|
18
|
-
JSON API maintains a (non-verified) listing of [client libraries](http://jsonapi.org/implementations/#client-libraries)
|
18
|
+
JSON API maintains a (non-verified) listing of [client libraries](http://jsonapi.org/implementations/#client-libraries)
|
19
19
|
which *should* be compatible with JSON API compliant server implementations such as JR.
|
20
20
|
|
21
21
|
## Installation
|
@@ -36,10 +36,10 @@ Or install it yourself as:
|
|
36
36
|
|
37
37
|
### Resources
|
38
38
|
|
39
|
-
Resources define the public interface to your API. A resource defines which attributes are exposed, as well as
|
39
|
+
Resources define the public interface to your API. A resource defines which attributes are exposed, as well as
|
40
40
|
relationships to other resources.
|
41
41
|
|
42
|
-
Resource definitions should by convention be placed in a directory under app named resources, `app/resources`. The class
|
42
|
+
Resource definitions should by convention be placed in a directory under app named resources, `app/resources`. The class
|
43
43
|
name should be the single underscored name of the model that backs the resource with `_resource.rb` appended. For example,
|
44
44
|
a `Contact` model's resource should have a class named `ContactResource` defined in a file named `contact_resource.rb`.
|
45
45
|
|
@@ -56,7 +56,7 @@ end
|
|
56
56
|
|
57
57
|
#### Attributes
|
58
58
|
|
59
|
-
Any of a resource's attributes that are accessible must be explicitly declared. Single attributes can be declared using
|
59
|
+
Any of a resource's attributes that are accessible must be explicitly declared. Single attributes can be declared using
|
60
60
|
the `attribute` method, and multiple attributes can be declared with the `attributes` method on the resource class.
|
61
61
|
|
62
62
|
For example:
|
@@ -68,10 +68,10 @@ class ContactResource < JSONAPI::Resource
|
|
68
68
|
end
|
69
69
|
```
|
70
70
|
|
71
|
-
This resource has 4 defined attributes: `name_first`, `name_last`, `email`, `twitter`, as well as the automatically
|
71
|
+
This resource has 4 defined attributes: `name_first`, `name_last`, `email`, `twitter`, as well as the automatically
|
72
72
|
defined attributes `id` and `type`. By default these attributes must exist on the model that is handled by the resource.
|
73
73
|
|
74
|
-
A resource object wraps a Ruby object, usually an `ActiveModel` record, which is available as the `@model` variable.
|
74
|
+
A resource object wraps a Ruby object, usually an `ActiveModel` record, which is available as the `@model` variable.
|
75
75
|
This allows a resource's methods to access the underlying model.
|
76
76
|
|
77
77
|
For example, a computed attribute for `full_name` could be defined as such:
|
@@ -89,7 +89,7 @@ end
|
|
89
89
|
|
90
90
|
##### Fetchable Attributes
|
91
91
|
|
92
|
-
By default all attributes are assumed to be fetchable. The list of fetchable attributes can be filtered by overriding
|
92
|
+
By default all attributes are assumed to be fetchable. The list of fetchable attributes can be filtered by overriding
|
93
93
|
the `fetchable_fields` method.
|
94
94
|
|
95
95
|
Here's an example that prevents guest users from seeing the `email` field:
|
@@ -115,7 +115,7 @@ value).
|
|
115
115
|
|
116
116
|
##### Creatable and Updatable Attributes
|
117
117
|
|
118
|
-
By default all attributes are assumed to be updatable and creatable. To prevent some attributes from being accepted by
|
118
|
+
By default all attributes are assumed to be updatable and creatable. To prevent some attributes from being accepted by
|
119
119
|
the `update` or `create` methods, override the `self.updatable_fields` and `self.creatable_fields` methods on a resource.
|
120
120
|
|
121
121
|
This example prevents `full_name` from being set:
|
@@ -145,7 +145,7 @@ By using the context you have the option to determine the creatable and updatabl
|
|
145
145
|
|
146
146
|
JR supports [sorting primary resources by multiple sort criteria](http://jsonapi.org/format/#fetching-sorting).
|
147
147
|
|
148
|
-
By default all attributes are assumed to be sortable. To prevent some attributes from being sortable, override the
|
148
|
+
By default all attributes are assumed to be sortable. To prevent some attributes from being sortable, override the
|
149
149
|
`self.sortable_fields` method on a resource.
|
150
150
|
|
151
151
|
Here's an example that prevents sorting by post's `body`:
|
@@ -162,7 +162,7 @@ end
|
|
162
162
|
|
163
163
|
##### Attribute Formatting
|
164
164
|
|
165
|
-
Attributes can have a `Format`. By default all attributes use the default formatter. If an attribute has the `format`
|
165
|
+
Attributes can have a `Format`. By default all attributes use the default formatter. If an attribute has the `format`
|
166
166
|
option set the system will attempt to find a formatter based on this name. In the following example the `last_login_time`
|
167
167
|
will be returned formatted to a certain time zone:
|
168
168
|
|
@@ -178,12 +178,12 @@ updating the attribute. See the [Value Formatters](#value-formatters) section fo
|
|
178
178
|
|
179
179
|
#### Primary Key
|
180
180
|
|
181
|
-
Resources are always represented using a key of `id`. If the underlying model does not use `id` as the primary key you
|
182
|
-
can use the `primary_key` method to tell the resource which field on the model to use as the primary key. Note: this
|
183
|
-
doesn't have to be the actual primary key of the model. For example you may wish to use integers internally and a
|
181
|
+
Resources are always represented using a key of `id`. If the underlying model does not use `id` as the primary key you
|
182
|
+
can use the `primary_key` method to tell the resource which field on the model to use as the primary key. Note: this
|
183
|
+
doesn't have to be the actual primary key of the model. For example you may wish to use integers internally and a
|
184
184
|
different scheme publicly.
|
185
185
|
|
186
|
-
By default only integer values are allowed for primary key. To change this behavior you can override
|
186
|
+
By default only integer values are allowed for primary key. To change this behavior you can override
|
187
187
|
`verify_key` class method:
|
188
188
|
|
189
189
|
```ruby
|
@@ -201,7 +201,7 @@ end
|
|
201
201
|
|
202
202
|
#### Model Name
|
203
203
|
|
204
|
-
The name of the underlying model is inferred from the Resource name. It can be overridden by use of the `model_name`
|
204
|
+
The name of the underlying model is inferred from the Resource name. It can be overridden by use of the `model_name`
|
205
205
|
method. For example:
|
206
206
|
|
207
207
|
```ruby
|
@@ -239,34 +239,64 @@ end
|
|
239
239
|
##### Options
|
240
240
|
|
241
241
|
The association methods support the following options:
|
242
|
+
|
242
243
|
* `class_name` - a string specifying the underlying class for the related resource
|
243
|
-
* `foreign_key` - the method on the resource used to fetch the related resource. Defaults to `<resource_name>_id` for
|
244
|
-
has_one and `<resource_name>_ids` for has_many relationships.
|
244
|
+
* `foreign_key` - the method on the resource used to fetch the related resource. Defaults to `<resource_name>_id` for has_one and `<resource_name>_ids` for has_many relationships.
|
245
245
|
* `acts_as_set` - allows the entire set of related records to be replaced in one operation. Defaults to false if not set.
|
246
|
+
* `polymorphic` - set to true to identify associations that are polymorphic.
|
247
|
+
* `relation_name` - the name of the relation to use on the model. A lambda may be provided which allows conditional selection of the relation based on the context.
|
246
248
|
|
247
249
|
Examples:
|
248
250
|
|
249
251
|
```ruby
|
250
|
-
|
252
|
+
class CommentResource < JSONAPI::Resource
|
251
253
|
attributes :body
|
252
254
|
has_one :post
|
253
255
|
has_one :author, class_name: 'Person'
|
254
256
|
has_many :tags, acts_as_set: true
|
255
|
-
|
256
|
-
```
|
257
|
+
end
|
257
258
|
|
258
|
-
```ruby
|
259
259
|
class ExpenseEntryResource < JSONAPI::Resource
|
260
260
|
attributes :cost, :transaction_date
|
261
261
|
|
262
262
|
has_one :currency, class_name: 'Currency', foreign_key: 'currency_code'
|
263
263
|
has_one :employee
|
264
264
|
end
|
265
|
+
|
266
|
+
class TagResource < JSONAPI::Resource
|
267
|
+
attributes :name
|
268
|
+
has_one :taggable, polymorphic: true
|
269
|
+
end
|
270
|
+
```
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
class BookResource < JSONAPI::Resource
|
274
|
+
|
275
|
+
# Only book_admins may see unapproved comments for a book. Using
|
276
|
+
# a lambda to select the correct relation on the model
|
277
|
+
has_many :book_comments, relation_name: -> (options = {}) {
|
278
|
+
context = options[:context]
|
279
|
+
current_user = context ? context[:current_user] : nil
|
280
|
+
|
281
|
+
unless current_user && current_user.book_admin
|
282
|
+
:approved_book_comments
|
283
|
+
else
|
284
|
+
:book_comments
|
285
|
+
end
|
286
|
+
}
|
287
|
+
...
|
288
|
+
end
|
289
|
+
|
290
|
+
The polymorphic association will require the resource and controller to exist, although routing to them will cause an error.
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
class TaggableResource < JSONAPI::Resource; end
|
294
|
+
class TaggablesController < JSONAPI::ResourceController; end
|
265
295
|
```
|
266
296
|
|
267
297
|
#### Filters
|
268
298
|
|
269
|
-
Filters for locating objects of the resource type are specified in the resource definition. Single filters can be
|
299
|
+
Filters for locating objects of the resource type are specified in the resource definition. Single filters can be
|
270
300
|
declared using the `filter` method, and multiple filters can be declared with the `filters` method on the resource class.
|
271
301
|
|
272
302
|
For example:
|
@@ -280,6 +310,8 @@ class ContactResource < JSONAPI::Resource
|
|
280
310
|
end
|
281
311
|
```
|
282
312
|
|
313
|
+
Then a request could pass in a filter for example `http://example.com/contacts?filter[name_last]=Smith` and the system will find all people where the last name exactly matches Smith.
|
314
|
+
|
283
315
|
##### Default Filters
|
284
316
|
|
285
317
|
A default filter may be defined for a resource using the `default` option on the `filter` method. This default is used
|
@@ -292,7 +324,7 @@ For example:
|
|
292
324
|
attributes :body, :status
|
293
325
|
has_one :post
|
294
326
|
has_one :author
|
295
|
-
|
327
|
+
|
296
328
|
filter :status, default: 'published,pending'
|
297
329
|
end
|
298
330
|
```
|
@@ -301,13 +333,13 @@ The default value is used as if it came from the request.
|
|
301
333
|
|
302
334
|
##### Finders
|
303
335
|
|
304
|
-
Basic finding by filters is supported by resources. This is implemented in the `find` and `find_by_key` finder methods.
|
336
|
+
Basic finding by filters is supported by resources. This is implemented in the `find` and `find_by_key` finder methods.
|
305
337
|
Currently this is implemented for `ActiveRecord` based resources. The finder methods rely on the `records` method to get
|
306
338
|
an `Arel` relation. It is therefore possible to override `records` to affect the three find related methods.
|
307
339
|
|
308
340
|
###### Customizing base records for finder methods
|
309
341
|
|
310
|
-
If you need to change the base records on which `find` and `find_by_key` operate, you can override the `records` method
|
342
|
+
If you need to change the base records on which `find` and `find_by_key` operate, you can override the `records` method
|
311
343
|
on the resource class.
|
312
344
|
|
313
345
|
For example to allow a user to only retrieve his own posts you can do the following:
|
@@ -323,7 +355,7 @@ class PostResource < JSONAPI::Resource
|
|
323
355
|
end
|
324
356
|
```
|
325
357
|
|
326
|
-
When you create a relationship, a method is created to fetch record(s) for that relationship. This method calls
|
358
|
+
When you create a relationship, a method is created to fetch record(s) for that relationship. This method calls
|
327
359
|
`records_for(association_name)` by default.
|
328
360
|
|
329
361
|
```ruby
|
@@ -361,7 +393,7 @@ end
|
|
361
393
|
|
362
394
|
###### Applying Filters
|
363
395
|
|
364
|
-
The `apply_filter` method is called to apply each filter to the `Arel` relation. You may override this method to gain
|
396
|
+
The `apply_filter` method is called to apply each filter to the `Arel` relation. You may override this method to gain
|
365
397
|
control over how the filters are applied to the `Arel` relation.
|
366
398
|
|
367
399
|
This example shows how you can implement different approaches for different filters.
|
@@ -388,7 +420,7 @@ end
|
|
388
420
|
|
389
421
|
###### Override finder methods
|
390
422
|
|
391
|
-
Finally if you have more complex requirements for finding you can override the `find` and `find_by_key` methods on the
|
423
|
+
Finally if you have more complex requirements for finding you can override the `find` and `find_by_key` methods on the
|
392
424
|
resource class.
|
393
425
|
|
394
426
|
Here's an example that defers the `find` operation to a `current_user` set on the `context` option:
|
@@ -414,24 +446,24 @@ end
|
|
414
446
|
|
415
447
|
#### Pagination
|
416
448
|
|
417
|
-
Pagination is performed using a `paginator`, which is a class responsible for parsing the `page` request parameters and
|
449
|
+
Pagination is performed using a `paginator`, which is a class responsible for parsing the `page` request parameters and
|
418
450
|
applying the pagination logic to the results.
|
419
451
|
|
420
452
|
##### Paginators
|
421
453
|
|
422
|
-
`JSONAPI::Resource` supports several pagination methods by default, and allows you to implement a custom system if the
|
454
|
+
`JSONAPI::Resource` supports several pagination methods by default, and allows you to implement a custom system if the
|
423
455
|
defaults do not meet your needs.
|
424
456
|
|
425
457
|
###### Paged Paginator
|
426
458
|
|
427
|
-
The `paged` `paginator` returns results based on pages of a fixed size. Valid `page` parameters are `number` and `size`.
|
428
|
-
If `number` is omitted the first page is returned. If `size` is omitted the `default_page_size` from the configuration
|
459
|
+
The `paged` `paginator` returns results based on pages of a fixed size. Valid `page` parameters are `number` and `size`.
|
460
|
+
If `number` is omitted the first page is returned. If `size` is omitted the `default_page_size` from the configuration
|
429
461
|
settings is used.
|
430
462
|
|
431
463
|
###### Offset Paginator
|
432
464
|
|
433
|
-
The `offset` `paginator` returns results based on an offset from the beginning of the resultset. Valid `page` parameters
|
434
|
-
are `offset` and `limit`. If `offset` is omitted a value of 0 will be used. If `limit` is omitted the `default_page_size`
|
465
|
+
The `offset` `paginator` returns results based on an offset from the beginning of the resultset. Valid `page` parameters
|
466
|
+
are `offset` and `limit`. If `offset` is omitted a value of 0 will be used. If `limit` is omitted the `default_page_size`
|
435
467
|
from the configuration settings is used.
|
436
468
|
|
437
469
|
###### Custom Paginators
|
@@ -457,7 +489,7 @@ end
|
|
457
489
|
|
458
490
|
##### Paginator Configuration
|
459
491
|
|
460
|
-
The default paginator, which will be used for all resources, is set using `JSONAPI.configure`. For example, in your
|
492
|
+
The default paginator, which will be used for all resources, is set using `JSONAPI.configure`. For example, in your
|
461
493
|
`config/initializers/jsonapi_resources.rb`:
|
462
494
|
|
463
495
|
```ruby
|
@@ -472,7 +504,7 @@ end
|
|
472
504
|
|
473
505
|
If no `default_paginator` is configured, pagination will be disabled by default.
|
474
506
|
|
475
|
-
Paginators can also be set at the resource-level, which will override the default setting. This is done using the
|
507
|
+
Paginators can also be set at the resource-level, which will override the default setting. This is done using the
|
476
508
|
`paginator` method:
|
477
509
|
|
478
510
|
```ruby
|
@@ -488,7 +520,7 @@ To disable pagination in a resource, specify `:none` for `paginator`.
|
|
488
520
|
|
489
521
|
#### Callbacks
|
490
522
|
|
491
|
-
`ActiveSupport::Callbacks` is used to provide callback functionality, so the behavior is very similar to what you may be
|
523
|
+
`ActiveSupport::Callbacks` is used to provide callback functionality, so the behavior is very similar to what you may be
|
492
524
|
used to from `ActiveRecord`.
|
493
525
|
|
494
526
|
For example, you might use a callback to perform authorization on your resource before an action.
|
@@ -544,13 +576,13 @@ Callbacks can also be defined for `JSONAPI::OperationsProcessor` events:
|
|
544
576
|
- `:remove_has_one_association_operation`: A `remove_has_one_association_operation`.
|
545
577
|
|
546
578
|
The operation callbacks have access to two meta data hashes, `@operations_meta` and `@operation_meta`, two links hashes,
|
547
|
-
`@operations_links` and `@operation_links`, the full list of `@operations`, each individual `@operation` and the
|
579
|
+
`@operations_links` and `@operation_links`, the full list of `@operations`, each individual `@operation` and the
|
548
580
|
`@result` variables.
|
549
581
|
|
550
582
|
##### Custom `OperationsProcessor` Example to Return total_count in Meta
|
551
583
|
|
552
584
|
Note: this can also be accomplished with the `top_level_meta_include_record_count` option, and in most cases that will
|
553
|
-
be the better option.
|
585
|
+
be the better option.
|
554
586
|
|
555
587
|
To return the total record count of a find operation in the meta data of a find operation you can create a custom
|
556
588
|
OperationsProcessor. For example:
|
@@ -565,14 +597,14 @@ end
|
|
565
597
|
|
566
598
|
Set the configuration option `operations_processor` to use the new `CountingActiveRecordOperationsProcessor` by
|
567
599
|
specifying the snake cased name of the class (without the `OperationsProcessor`).
|
568
|
-
|
600
|
+
|
569
601
|
```ruby
|
570
602
|
JSONAPI.configure do |config|
|
571
603
|
config.operations_processor = :counting_active_record
|
572
604
|
end
|
573
605
|
```
|
574
606
|
|
575
|
-
The callback code will be called after each find. It will use the same options as the find operation, without the
|
607
|
+
The callback code will be called after each find. It will use the same options as the find operation, without the
|
576
608
|
pagination, to collect the record count. This is stored in the `operation_meta`, which will be returned in the top level
|
577
609
|
meta element.
|
578
610
|
|
@@ -583,8 +615,8 @@ the `ActsAsResourceController` module.
|
|
583
615
|
|
584
616
|
##### ResourceController
|
585
617
|
|
586
|
-
`JSONAPI::Resources` provides a class, `ResourceController`, that can be used as the base class for your controllers.
|
587
|
-
`ResourceController` supports `index`, `show`, `create`, `update`, and `destroy` methods. Just deriving your controller
|
618
|
+
`JSONAPI::Resources` provides a class, `ResourceController`, that can be used as the base class for your controllers.
|
619
|
+
`ResourceController` supports `index`, `show`, `create`, `update`, and `destroy` methods. Just deriving your controller
|
588
620
|
from `ResourceController` will give you a fully functional controller.
|
589
621
|
|
590
622
|
For example:
|
@@ -634,7 +666,7 @@ JSONAPI::Resources supports namespacing of controllers and resources. With names
|
|
634
666
|
|
635
667
|
If you namespace your controller it will require a namespaced resource.
|
636
668
|
|
637
|
-
In the following example we have a `resource` that isn't namespaced, and one the has now been namespaced. There are
|
669
|
+
In the following example we have a `resource` that isn't namespaced, and one the has now been namespaced. There are
|
638
670
|
slight differences between the two resources, as might be seen in a new version of an API:
|
639
671
|
|
640
672
|
```ruby
|
@@ -793,14 +825,14 @@ This returns results like this:
|
|
793
825
|
"relationships": {
|
794
826
|
"section": {
|
795
827
|
"links": {
|
796
|
-
"self": "http://example.com/posts/1/
|
828
|
+
"self": "http://example.com/posts/1/relationships/section",
|
797
829
|
"related": "http://example.com/posts/1/section"
|
798
830
|
},
|
799
831
|
"data": null
|
800
832
|
},
|
801
833
|
"author": {
|
802
834
|
"links": {
|
803
|
-
"self": "http://example.com/posts/1/
|
835
|
+
"self": "http://example.com/posts/1/relationships/author",
|
804
836
|
"related": "http://example.com/posts/1/author"
|
805
837
|
},
|
806
838
|
"data": {
|
@@ -810,13 +842,13 @@ This returns results like this:
|
|
810
842
|
},
|
811
843
|
"tags": {
|
812
844
|
"links": {
|
813
|
-
"self": "http://example.com/posts/1/
|
845
|
+
"self": "http://example.com/posts/1/relationships/tags",
|
814
846
|
"related": "http://example.com/posts/1/tags"
|
815
847
|
}
|
816
848
|
},
|
817
849
|
"comments": {
|
818
850
|
"links": {
|
819
|
-
"self": "http://example.com/posts/1/
|
851
|
+
"self": "http://example.com/posts/1/relationships/comments",
|
820
852
|
"related": "http://example.com/posts/1/comments"
|
821
853
|
}
|
822
854
|
}
|
@@ -841,7 +873,7 @@ An array of resources. Nested resources can be specified with dot notation.
|
|
841
873
|
|
842
874
|
A hash of resource types and arrays of fields for each resource type.
|
843
875
|
|
844
|
-
*Purpose*: determines which fields are serialized for a resource type. This encompasses both attributes and
|
876
|
+
*Purpose*: determines which fields are serialized for a resource type. This encompasses both attributes and
|
845
877
|
association ids in the links section for a resource. Fields are global for a resource type.
|
846
878
|
|
847
879
|
*Example*: ```fields: { people: [:email, :comments], posts: [:title, :author], comments: [:body, :post]}```
|
@@ -936,7 +968,7 @@ gives routes that are only related to the primary resource, and none for its rel
|
|
936
968
|
```
|
937
969
|
|
938
970
|
To manually add in the nested routes you can use the `jsonapi_links`, `jsonapi_related_resources` and
|
939
|
-
`jsonapi_related_resource` inside the block. Or, you can add the default set of nested routes using the
|
971
|
+
`jsonapi_related_resource` inside the block. Or, you can add the default set of nested routes using the
|
940
972
|
`jsonapi_relationships` method. For example:
|
941
973
|
|
942
974
|
```ruby
|
@@ -1033,11 +1065,11 @@ phone_number_contact GET /phone-numbers/:phone_number_id/contact(.:format) co
|
|
1033
1065
|
|
1034
1066
|
#### Formatting
|
1035
1067
|
|
1036
|
-
JR by default uses some simple rules to format an attribute for serialization. Strings and Integers are output to JSON
|
1037
|
-
as is, and all other values have `.to_s` applied to them. This outputs something in all cases, but it is certainly not
|
1068
|
+
JR by default uses some simple rules to format an attribute for serialization. Strings and Integers are output to JSON
|
1069
|
+
as is, and all other values have `.to_s` applied to them. This outputs something in all cases, but it is certainly not
|
1038
1070
|
correct for every situation.
|
1039
1071
|
|
1040
|
-
If you want to change the way an attribute is serialized you have a couple of ways. The simplest method is to create a
|
1072
|
+
If you want to change the way an attribute is serialized you have a couple of ways. The simplest method is to create a
|
1041
1073
|
getter method on the resource which overrides the attribute and apply the formatting there. For example:
|
1042
1074
|
|
1043
1075
|
```ruby
|
@@ -1051,13 +1083,13 @@ class PersonResource < JSONAPI::Resource
|
|
1051
1083
|
end
|
1052
1084
|
```
|
1053
1085
|
|
1054
|
-
This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
|
1055
|
-
to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
|
1086
|
+
This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
|
1087
|
+
to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
|
1056
1088
|
response, whether you want it or not.
|
1057
1089
|
|
1058
1090
|
##### Value Formatters
|
1059
1091
|
|
1060
|
-
To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
|
1092
|
+
To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
|
1061
1093
|
handled for an attribute. The `format` can be set per attribute as it is declared in the resource. For example:
|
1062
1094
|
|
1063
1095
|
```ruby
|
@@ -1067,7 +1099,7 @@ class PersonResource < JSONAPI::Resource
|
|
1067
1099
|
end
|
1068
1100
|
```
|
1069
1101
|
|
1070
|
-
A Value formatter has a `format` and an `unformat` method. Here's the base ValueFormatter and DefaultValueFormatter for
|
1102
|
+
A Value formatter has a `format` and an `unformat` method. Here's the base ValueFormatter and DefaultValueFormatter for
|
1071
1103
|
reference:
|
1072
1104
|
|
1073
1105
|
```ruby
|
@@ -1100,21 +1132,21 @@ class DefaultValueFormatter < JSONAPI::ValueFormatter
|
|
1100
1132
|
end
|
1101
1133
|
```
|
1102
1134
|
|
1103
|
-
You can also create your own Value Formatter. Value Formatters must be named with the `format` name followed by
|
1135
|
+
You can also create your own Value Formatter. Value Formatters must be named with the `format` name followed by
|
1104
1136
|
`ValueFormatter`, i.e. `DateWithUTCTimezoneValueFormatter` and derive from `JSONAPI::ValueFormatter`. It is
|
1105
1137
|
recommended that you create a directory for your formatters, called `formatters`.
|
1106
1138
|
|
1107
|
-
The `format` method is called by the `ResourceSerializer` as is serializing a resource. The format method takes the
|
1139
|
+
The `format` method is called by the `ResourceSerializer` as is serializing a resource. The format method takes the
|
1108
1140
|
`raw_value` parameter. `raw_value` is the value as read from the model.
|
1109
1141
|
|
1110
|
-
The `unformat` method is called when processing the request. Each incoming attribute (except `links`) are run through
|
1111
|
-
the `unformat` method. The `unformat` method takes a `value`, which is the value as it comes in on the
|
1142
|
+
The `unformat` method is called when processing the request. Each incoming attribute (except `links`) are run through
|
1143
|
+
the `unformat` method. The `unformat` method takes a `value`, which is the value as it comes in on the
|
1112
1144
|
request. This allows you process the incoming value to alter its state before it is stored in the model.
|
1113
1145
|
|
1114
1146
|
###### Use a Different Default Value Formatter
|
1115
1147
|
|
1116
|
-
Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
|
1117
|
-
not have a `format` set. You can do this by overriding the `default_attribute_options` method for a resource (or a base
|
1148
|
+
Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
|
1149
|
+
not have a `format` set. You can do this by overriding the `default_attribute_options` method for a resource (or a base
|
1118
1150
|
resource for a system wide change).
|
1119
1151
|
|
1120
1152
|
```ruby
|
@@ -1146,11 +1178,11 @@ This way all DateTime values will be formatted to display in the UTC timezone.
|
|
1146
1178
|
|
1147
1179
|
#### Key Format
|
1148
1180
|
|
1149
|
-
By default JR uses dasherized keys as per the
|
1150
|
-
[JSON API naming recommendations](http://jsonapi.org/recommendations/#naming). This can be changed by specifying a
|
1181
|
+
By default JR uses dasherized keys as per the
|
1182
|
+
[JSON API naming recommendations](http://jsonapi.org/recommendations/#naming). This can be changed by specifying a
|
1151
1183
|
different key formatter.
|
1152
1184
|
|
1153
|
-
For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
|
1185
|
+
For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
|
1154
1186
|
the following:
|
1155
1187
|
|
1156
1188
|
```ruby
|
@@ -1160,7 +1192,7 @@ JSONAPI.configure do |config|
|
|
1160
1192
|
end
|
1161
1193
|
```
|
1162
1194
|
|
1163
|
-
This will cause the serializer to use the `CamelizedKeyFormatter`. You can also create your own `KeyFormatter`, for
|
1195
|
+
This will cause the serializer to use the `CamelizedKeyFormatter`. You can also create your own `KeyFormatter`, for
|
1164
1196
|
example:
|
1165
1197
|
|
1166
1198
|
```ruby
|
@@ -1177,7 +1209,7 @@ You would specify this in `JSONAPI.configure` as `:upper_camelized`.
|
|
1177
1209
|
|
1178
1210
|
## Configuration
|
1179
1211
|
|
1180
|
-
JR has a few configuration options. Some have already been mentioned above. To set configuration options create an
|
1212
|
+
JR has a few configuration options. Some have already been mentioned above. To set configuration options create an
|
1181
1213
|
initializer and add the options you wish to set. All options have defaults, so you only need to set the options that
|
1182
1214
|
are different. The default options are shown below.
|
1183
1215
|
|