jei 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +474 -6
- data/lib/jei.rb +15 -13
- data/lib/jei/attribute.rb +1 -19
- data/lib/jei/builders/attributes_node_builder.rb +5 -3
- data/lib/jei/builders/data_node_builder.rb +3 -1
- data/lib/jei/builders/document_builder.rb +24 -31
- data/lib/jei/builders/included_node_builder.rb +9 -6
- data/lib/jei/builders/links_node_builder.rb +3 -1
- data/lib/jei/builders/relationship_node_builder.rb +6 -4
- data/lib/jei/builders/relationships_node_builder.rb +5 -3
- data/lib/jei/builders/resource_node_builder.rb +13 -6
- data/lib/jei/document.rb +14 -10
- data/lib/jei/error.rb +4 -0
- data/lib/jei/field.rb +22 -0
- data/lib/jei/fieldset.rb +15 -0
- data/lib/jei/nodes/attribute_node.rb +14 -12
- data/lib/jei/nodes/attributes_node.rb +9 -7
- data/lib/jei/nodes/collection_data_node.rb +10 -8
- data/lib/jei/nodes/data_node.rb +14 -12
- data/lib/jei/nodes/document_node.rb +7 -5
- data/lib/jei/nodes/included_node.rb +9 -7
- data/lib/jei/nodes/json_api_node.rb +7 -5
- data/lib/jei/nodes/link_node.rb +17 -15
- data/lib/jei/nodes/links_node.rb +9 -7
- data/lib/jei/nodes/meta_node.rb +12 -10
- data/lib/jei/nodes/node.rb +13 -11
- data/lib/jei/nodes/relationship_node.rb +14 -12
- data/lib/jei/nodes/relationships_node.rb +9 -7
- data/lib/jei/nodes/resource_identifier_node.rb +13 -11
- data/lib/jei/nodes/resource_node.rb +7 -5
- data/lib/jei/path.rb +13 -12
- data/lib/jei/relationship.rb +8 -5
- data/lib/jei/serializer.rb +70 -12
- data/lib/jei/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bf0d7bbd5077695a2e1219961576f894a5cd41f
|
4
|
+
data.tar.gz: 34cb6f17efada6cd82e01d23e8e67a16f7f2414e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89a27cbfe0af409953efaf4da6d83f7a8f78659bf2ca58a40a22a1b148d8df1eb9d48a2b65e76f374b38598618a2fcf8310b425d001977ef0580a2a3186ed59b
|
7
|
+
data.tar.gz: 5972dc16d4c2df09654730607ffbfa92165751a12fc3c6284923b4516af448c987e2b7747f99c4d39bf7266bfb09a5915b0bec0b2496685049bd5388c78764e3
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## HEAD
|
4
|
+
|
5
|
+
## 0.2.0 (2016-03-22)
|
6
|
+
|
7
|
+
* [ADD] Add `:fields` document build option for sparse fieldsets.
|
8
|
+
* [BREAKING] A relationship links `Proc` is no longer passed the context as
|
9
|
+
an argument. Update usages of `links: ->(_) {}` to `links: -> {}`.
|
10
|
+
* [ADD] Raise `Jei::Path::NameError` on bad relationship names.
|
11
|
+
* [BREAKING] Rename relationship option `no_data` to `data`. Take the
|
12
|
+
inverse of each occurance to update, e.g., change `no_data: true` to
|
13
|
+
`data: false`.
|
14
|
+
* [ADD] Add `:serializer` option to relationships to override the default
|
15
|
+
serializer class used.
|
16
|
+
* [CHANGE] Serializers are compared via a `(type, id)` tuple rather than
|
17
|
+
object identity.
|
18
|
+
* [FIX] Fix include usage when serializing a collection.
|
19
|
+
|
20
|
+
## 0.1.0 (2016-03-15)
|
21
|
+
|
22
|
+
* Initial release
|
data/README.md
CHANGED
@@ -17,6 +17,7 @@ install it manually.
|
|
17
17
|
```ruby
|
18
18
|
require 'jei'
|
19
19
|
|
20
|
+
# Create resource serializers.
|
20
21
|
class ArtistSerializer < Jei::Serializer
|
21
22
|
attribute :name
|
22
23
|
has_many :albums
|
@@ -26,18 +27,15 @@ class AlbumSerializer < Jei::Serializer
|
|
26
27
|
belongs_to :artist
|
27
28
|
end
|
28
29
|
|
29
|
-
class Artist < OpenStruct; end
|
30
|
-
class Album < OpenStruct; end
|
31
|
-
|
32
30
|
artist = Artist.new(id: 1, name: 'FIESTAR', albums: [])
|
33
|
-
|
31
|
+
artist.albums << Album.new(id: 1, artist: artist)
|
32
|
+
artist.albums << Album.new(id: 2, artist: artist)
|
34
33
|
|
34
|
+
# Build a JSON API document from the resource.
|
35
35
|
document = Jei::Document.build(artist)
|
36
36
|
document.to_json
|
37
37
|
```
|
38
38
|
|
39
|
-
This emits
|
40
|
-
|
41
39
|
```json
|
42
40
|
{
|
43
41
|
"data": {
|
@@ -57,3 +55,473 @@ This emits
|
|
57
55
|
}
|
58
56
|
}
|
59
57
|
```
|
58
|
+
|
59
|
+
### Serializers
|
60
|
+
|
61
|
+
A `Serializer` defines what attributes and relationships are serialized in a
|
62
|
+
document.
|
63
|
+
|
64
|
+
Jei uses reflection to automatically find the correct serailizer for a
|
65
|
+
resource. To do this, create a class that extends `Jei::Serializer` and name it
|
66
|
+
`#{resource.class.name}Serializer`. For example, an `Artist` resource would
|
67
|
+
have a matching serializer named `ArtistSerializer` in the global namespace.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class Artist; end
|
71
|
+
class ArtistSerializer < Jei::Serializer; end
|
72
|
+
```
|
73
|
+
|
74
|
+
#### Attributes
|
75
|
+
|
76
|
+
Attributes represent model data. They are defined in a serializer by using the
|
77
|
+
`attribute` or `attributes` methods.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
class AlbumSerializer < Jei::Serializer
|
81
|
+
# Attributes can be listed by name. Each name is used as an attribute key
|
82
|
+
# and its value is invoked by its name on the resource.
|
83
|
+
attributes :kind, :name
|
84
|
+
|
85
|
+
# Attributes can also be added individually.
|
86
|
+
attribute :released_on
|
87
|
+
|
88
|
+
# This is useful because `attribute` optionally takes a block. It can be
|
89
|
+
# used to rename an attribute in the document when the resource responds to
|
90
|
+
# a different name.
|
91
|
+
attribute(:release_date) { resource.released_on }
|
92
|
+
|
93
|
+
# Or it can be use to create entirely new attributes and values.
|
94
|
+
attribute :formatted_name do
|
95
|
+
date = resource.released_on.strftime('%Y.%m.%d')
|
96
|
+
"[#{date}] #{resource.name}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
album = Album.new(id: 1, kind: :ep, name: 'A Delicate Sense', released_on: Date.new(2016, 3, 9))
|
101
|
+
Jei::Document.build(album).to_json
|
102
|
+
```
|
103
|
+
|
104
|
+
```json
|
105
|
+
{
|
106
|
+
"data": {
|
107
|
+
"id": "1",
|
108
|
+
"type": "albums",
|
109
|
+
"attributes": {
|
110
|
+
"kind": "ep",
|
111
|
+
"name": "A Delicate Sense",
|
112
|
+
"released_on": "2016-03-09",
|
113
|
+
"release_date": "2016-03-09",
|
114
|
+
"formatted_name": "[2016.03.09] A Delicate Sense"
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
```
|
119
|
+
|
120
|
+
#### Relationships
|
121
|
+
|
122
|
+
Relationships describe how the primary resource relates to other resources. A
|
123
|
+
one-to-one relationship is defined by the `belongs_to` method, and a
|
124
|
+
one-to-many relationship, `has_many`.
|
125
|
+
|
126
|
+
The relationship names are invoked on the resource. A
|
127
|
+
belongs-to relationship returns a single resource, whereas has-many returns a
|
128
|
+
collection.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
class AlbumSerializer < Jei::Serializer
|
132
|
+
belongs_to :artist
|
133
|
+
has_many :tracks
|
134
|
+
|
135
|
+
# Like attributes, relationships can also take a block to override its value.
|
136
|
+
has_many :even_tracks do
|
137
|
+
resource.tracks.select { |t| t.id.even? }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class ArtistSerializer < Jei::Serializer; end
|
142
|
+
class TrackSerializer < Jei::Serializer; end
|
143
|
+
|
144
|
+
artist = Artist.new(id: 1)
|
145
|
+
tracks = [Track.new(id: 1), Track.new(id: 2)]
|
146
|
+
album = Album.new(id: 1, artist: artist, tracks: tracks)
|
147
|
+
|
148
|
+
Jei::Document.build(album).to_json
|
149
|
+
```
|
150
|
+
|
151
|
+
```json
|
152
|
+
{
|
153
|
+
"data": {
|
154
|
+
"id": "1",
|
155
|
+
"type": "albums",
|
156
|
+
"relationships": {
|
157
|
+
"artist": {
|
158
|
+
"data": { "id": "1", "type": "artists" }
|
159
|
+
},
|
160
|
+
"tracks": {
|
161
|
+
"data": [
|
162
|
+
{ "id": "1", "type": "tracks" },
|
163
|
+
{ "id": "2", "type": "tracks" }
|
164
|
+
]
|
165
|
+
},
|
166
|
+
"even_tracks": {
|
167
|
+
"data": [
|
168
|
+
{ "id": "2", "type": "tracks" }
|
169
|
+
]
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
```
|
175
|
+
|
176
|
+
##### Options
|
177
|
+
|
178
|
+
Each relationship object can be modified with the following options.
|
179
|
+
|
180
|
+
* `data`: (`Boolean`; default: `true`) Setting this to `false` supresses
|
181
|
+
building a data object with resource identifiers. Note that doing so does not
|
182
|
+
emit a valid JSON API document unless a links or meta object is present.
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
class ArtistSerializer < Jei::Serializer
|
186
|
+
has_many :albums, data: false
|
187
|
+
end
|
188
|
+
|
189
|
+
albums = [Album.new(id: 1), Album.new(id: 2)]
|
190
|
+
artist = Artist.new(id: 1, albums: albums)
|
191
|
+
|
192
|
+
Jei::Document.build(artist).to_json
|
193
|
+
```
|
194
|
+
|
195
|
+
```json
|
196
|
+
{
|
197
|
+
"data": {
|
198
|
+
"id": "1",
|
199
|
+
"type": "artists",
|
200
|
+
"relationships": {
|
201
|
+
"albums": {}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
```
|
206
|
+
|
207
|
+
* `links`: (`Proc -> Array<Jei::Link>`) This is for relationship level links.
|
208
|
+
The `Proc` must return a list of `Link`s and is run in the context of the
|
209
|
+
serializer.
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
class ArtistSerializer < Jei::Serializer
|
213
|
+
has_many :albums, links: -> {
|
214
|
+
[Jei::Link.new(:related, "/#{type}/#{id}/albums")]
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
class AlbumSerializer < Jei::Serializer; end
|
219
|
+
|
220
|
+
albums = [Album.new(id: 1), Album.new(id: 2)]
|
221
|
+
artist = Artist.new(id: 1, albums: albums)
|
222
|
+
Jei::Document.build(artist).to_json
|
223
|
+
```
|
224
|
+
|
225
|
+
```json
|
226
|
+
{
|
227
|
+
"data": {
|
228
|
+
"id": "1",
|
229
|
+
"type": "artists",
|
230
|
+
"relationships": {
|
231
|
+
"albums": {
|
232
|
+
"data": [
|
233
|
+
{ "id": "1", "type": "albums" },
|
234
|
+
{ "id": "2", "type": "albums" }
|
235
|
+
],
|
236
|
+
"links": {
|
237
|
+
"related": "/artists/1/albums"
|
238
|
+
}
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
```
|
244
|
+
|
245
|
+
* `serializer`: (`Class`) Overrides the default serializer used for each
|
246
|
+
related resource.
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
class RecordSerializer < Jei::Serializer
|
250
|
+
def type
|
251
|
+
'records'
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
class ArtistSerializer < Jei::Serializer
|
256
|
+
has_many :albums, serializer: RecordSerializer
|
257
|
+
end
|
258
|
+
|
259
|
+
artist = Artist.new(id: 1, albums: [Album.new(id: 1)])
|
260
|
+
Jei::Document.build(artist).to_json
|
261
|
+
```
|
262
|
+
|
263
|
+
```json
|
264
|
+
{
|
265
|
+
"data": {
|
266
|
+
"id": "1",
|
267
|
+
"type": "artists",
|
268
|
+
"relationships": {
|
269
|
+
"albums": {
|
270
|
+
"data": [
|
271
|
+
{ "id": "1", "type": "records" }
|
272
|
+
]
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
}
|
277
|
+
```
|
278
|
+
|
279
|
+
### Document
|
280
|
+
|
281
|
+
As seen in previous examples, `Jei::Document` represents a JSON API document.
|
282
|
+
After building the structure from a resource or collection of resources using
|
283
|
+
`Document.build`, it can be serialized to a Ruby hash (`#to_h`) or a JSON
|
284
|
+
string (`#to_json`).
|
285
|
+
|
286
|
+
#### Options
|
287
|
+
|
288
|
+
Top level objects can be added using the following options.
|
289
|
+
|
290
|
+
* `:fields`: (`Hash<String, String>`) A map of resource type-fields that define
|
291
|
+
sparse fieldsets. Keys are resource types, and fields are a comma-separated
|
292
|
+
list of field names. For example, `{ 'artists' => 'name,albums', 'albums' =>
|
293
|
+
'released_on' }`.
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
class ArtistSerializer < Jei::Serializer
|
297
|
+
attributes :kind, :name
|
298
|
+
has_many :albums
|
299
|
+
end
|
300
|
+
|
301
|
+
artist = Artist.new(id: 1, kind: :group, name: 'FIESTAR', albums: [])
|
302
|
+
|
303
|
+
Jei::Document.build(artist, fields: { 'artists' => 'name' }).to_json
|
304
|
+
```
|
305
|
+
|
306
|
+
```json
|
307
|
+
{
|
308
|
+
"data": {
|
309
|
+
"id": "1",
|
310
|
+
"type": "artists",
|
311
|
+
"attributes": {
|
312
|
+
"name": "FIESTAR"
|
313
|
+
}
|
314
|
+
}
|
315
|
+
}
|
316
|
+
```
|
317
|
+
|
318
|
+
* `:include`: (`String`) A comma separated list of relationship paths. Each
|
319
|
+
path is a list of relationship names, separated by a period. For example, a
|
320
|
+
valid list of paths would be `artist,tracks.song`. The set of resources are
|
321
|
+
all unique resources on the include path.
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
class ArtistSerializer < Jei::Serializer
|
325
|
+
attribute :name
|
326
|
+
has_many :albums
|
327
|
+
end
|
328
|
+
|
329
|
+
class AlbumSerializer < Jei::Serializer
|
330
|
+
attributes :name, :release_date
|
331
|
+
belongs_to :artist
|
332
|
+
has_many :tracks
|
333
|
+
end
|
334
|
+
|
335
|
+
class TrackSerializer < Jei::Serializer
|
336
|
+
attributes :position, :name
|
337
|
+
belongs_to :album
|
338
|
+
end
|
339
|
+
|
340
|
+
artist = Artist.new(id: 1, name: 'FIESTAR')
|
341
|
+
album1 = Album.new(id: 1, name: 'A Delicate Sense', release_date: '2016-03-09', artist: artist)
|
342
|
+
album2 = Album.new(id: 2, name: 'Black Label', release_date: '2015-03-04', artist: artist)
|
343
|
+
artist.albums = [album1, album2]
|
344
|
+
album1.tracks = [Track.new(id: 1, position: 2, name: 'Mirror', album: album1)]
|
345
|
+
album2.tracks = [Track.new(id: 2, position: 1, name: "You're Pitiful", album: album2)]
|
346
|
+
|
347
|
+
Jei::Document.build(artist, include: 'albums.tracks').to_json
|
348
|
+
```
|
349
|
+
|
350
|
+
```json
|
351
|
+
{
|
352
|
+
"data": {
|
353
|
+
"id": "1",
|
354
|
+
"type": "artists",
|
355
|
+
"attributes": {
|
356
|
+
"name": "FIESTAR"
|
357
|
+
},
|
358
|
+
"relationships": {
|
359
|
+
"albums": {
|
360
|
+
"data": [
|
361
|
+
{ "id": "1", "type": "albums" },
|
362
|
+
{ "id": "2", "type": "albums" }
|
363
|
+
]
|
364
|
+
}
|
365
|
+
}
|
366
|
+
},
|
367
|
+
"included": [
|
368
|
+
{
|
369
|
+
"id": "1",
|
370
|
+
"type": "albums",
|
371
|
+
"attributes": {
|
372
|
+
"name": "A Delicate Sense",
|
373
|
+
"release_date": "2016-03-09"
|
374
|
+
},
|
375
|
+
"relationships": {
|
376
|
+
"artist": {
|
377
|
+
"data": { "id": "1", "type": "artists" }
|
378
|
+
},
|
379
|
+
"tracks": {
|
380
|
+
"data": [
|
381
|
+
{ "id": "1", "type": "tracks" }
|
382
|
+
]
|
383
|
+
}
|
384
|
+
}
|
385
|
+
},
|
386
|
+
// ...
|
387
|
+
]
|
388
|
+
}
|
389
|
+
```
|
390
|
+
|
391
|
+
* `:jsonapi`: (`Boolean`) Includes a JSON API object in top level of the
|
392
|
+
document.
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
Jei::Document.build(nil, jsonapi: true).to_json
|
396
|
+
```
|
397
|
+
|
398
|
+
```json
|
399
|
+
{
|
400
|
+
"jsonapi": {
|
401
|
+
"version": "1.0"
|
402
|
+
},
|
403
|
+
"data": null
|
404
|
+
}
|
405
|
+
```
|
406
|
+
|
407
|
+
* `:links`: (`Array<Link>`) Includes a links object in the top level of the
|
408
|
+
document.
|
409
|
+
|
410
|
+
```ruby
|
411
|
+
links = [
|
412
|
+
Jei::Link.new(:self, '/artists?page[number]=2'),
|
413
|
+
Jei::Link.new(:prev, '/artists?page[number]=1'),
|
414
|
+
Jei::Link.new(:next, '/artists?page[number]=3')
|
415
|
+
]
|
416
|
+
Jei::Document.build(nil, links: links).to_json
|
417
|
+
```
|
418
|
+
|
419
|
+
```json
|
420
|
+
{
|
421
|
+
"links": {
|
422
|
+
"self": "/artists?page[number]=2",
|
423
|
+
"prev": "/artists?page[number]=1",
|
424
|
+
"next": "/artists?page[number]=3"
|
425
|
+
},
|
426
|
+
"data": null
|
427
|
+
}
|
428
|
+
```
|
429
|
+
|
430
|
+
* `:meta`: (`Hash<Symbol, Object>`) Includes a meta object in the top level of
|
431
|
+
the document.
|
432
|
+
|
433
|
+
```ruby
|
434
|
+
Jei::Document.build(nil, meta: { total_pages: 10 }).to_json
|
435
|
+
```
|
436
|
+
|
437
|
+
```json
|
438
|
+
{
|
439
|
+
"meta": {
|
440
|
+
"total_pages": 10
|
441
|
+
},
|
442
|
+
"data": null
|
443
|
+
}
|
444
|
+
```
|
445
|
+
|
446
|
+
* `:serializer`: (`Class`) Overrides the default serializer used for the
|
447
|
+
primary resource.
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
class SimpleArtistSerializer < Jei::Serializer
|
451
|
+
attribute :name
|
452
|
+
end
|
453
|
+
|
454
|
+
artist = Artist.new(id: 1, name: 'FIESTAR')
|
455
|
+
Jei::Document.build(artist, serializer: SimpleArtistSerializer).to_json
|
456
|
+
```
|
457
|
+
|
458
|
+
```json
|
459
|
+
{
|
460
|
+
"data": {
|
461
|
+
"id": "1",
|
462
|
+
"type": "artists",
|
463
|
+
"attributes": {
|
464
|
+
"name": "FIESTAR"
|
465
|
+
}
|
466
|
+
}
|
467
|
+
}
|
468
|
+
```
|
469
|
+
|
470
|
+
## Integration
|
471
|
+
|
472
|
+
Jei is not tied to any framework and can be integrated as a normal gem.
|
473
|
+
|
474
|
+
### Rails
|
475
|
+
|
476
|
+
The simplest usage with [Rails][rails] is to define a new renderer.
|
477
|
+
|
478
|
+
```ruby
|
479
|
+
# config/initializers/jei.rb
|
480
|
+
ActionController::Renderers.add(:jsonapi) do |resource, options|
|
481
|
+
document = Jei::Document.build(resource, options)
|
482
|
+
json = document.to_json
|
483
|
+
self.content_type = Mime::Type.lookup_by_extension(:jsonapi)
|
484
|
+
self.response_body = json
|
485
|
+
end
|
486
|
+
|
487
|
+
# config/initializers/mime_types.rb
|
488
|
+
Mime::Type.register 'application/vnd.api+json', :jsonapi
|
489
|
+
```
|
490
|
+
|
491
|
+
Serializers can be placed in `app/serializers`. Include Rails' url helpers to
|
492
|
+
have them conveniently accessible in the serializer context for links.
|
493
|
+
|
494
|
+
```ruby
|
495
|
+
# app/serializers/application_serializer.rb
|
496
|
+
class ApplicationSerializer < Jei::Serializer
|
497
|
+
include Rails.application.routes.url_helpers
|
498
|
+
end
|
499
|
+
|
500
|
+
# app/serializers/album_serializer.rb
|
501
|
+
class AlbumSerializer < ApplicationSerializer
|
502
|
+
attributes :kind, :name, :release_date
|
503
|
+
belongs_to :artist
|
504
|
+
end
|
505
|
+
|
506
|
+
# app/serializers/artist_serializer.rb
|
507
|
+
class ArtistSerializer < ApplicationSerializer
|
508
|
+
attributes :name
|
509
|
+
has_many :albums, data: false, links: -> {
|
510
|
+
[Jei::Link.new(:related, album_path(resource))]
|
511
|
+
}
|
512
|
+
end
|
513
|
+
```
|
514
|
+
|
515
|
+
Specify the `jsonapi` format defined earlier when rendering in a controller.
|
516
|
+
|
517
|
+
```ruby
|
518
|
+
# app/controllers/artists_controller.rb
|
519
|
+
class ArtistsController < ApplicationController
|
520
|
+
def show
|
521
|
+
artist = Artist.find(params[:id])
|
522
|
+
render jsonapi: artist, include: params[:include]
|
523
|
+
end
|
524
|
+
end
|
525
|
+
```
|
526
|
+
|
527
|
+
[rails]: http://rubyonrails.org/
|