roar 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b58dcace50d4224e36f81444ce64ca73dfec11a
4
- data.tar.gz: 419929c85da4aef8a13243364b1c918acfd5312c
3
+ metadata.gz: 9ce6093e4d27114a605b64621c20ab9f5e156266
4
+ data.tar.gz: ac05b9e8989952f88b86caaf2d344a2467f48968
5
5
  SHA512:
6
- metadata.gz: c090f6a70e513ab5ad28155a9c21a453f0e37a289acb2af3a7ade51484d8cc1a76d0c14a02cf6343b054fb9ef2dd392dcae2383b7d219c77e43513d370369c62
7
- data.tar.gz: 3253825814038580793eebb22da120b3af1ce69723d81283b65953e5b30806a91b7627ebb370de30b46440b07b749465ec2db1a9235b884b5de132becf2d4c84
6
+ metadata.gz: 334f83c90798c648945a3d1f0077e503a26f6a51bd2499a3878f48bdb845ad3815a55f8e372078ac28cf5fba628043e7b4edb031625e1abf14ff36dc4fee890d
7
+ data.tar.gz: 329f87d78af5d6e8f214e5dc71a22ff9ce932967bc8bb0e86f5b45ecad6a21eabf546afecd0690ab05dc8e5ccbcfe5f98cfccddc2ddd18f381e6a7ddaf2e441e
@@ -1,3 +1,7 @@
1
+ # 1.0.1
2
+
3
+ * Allow calling `::has_one`, `::links` and `::has_many` in any order in JSON-API. This requires representable >= 2.1.4.
4
+
1
5
  # 1.0.0
2
6
 
3
7
  ## Breakage
data/Gemfile CHANGED
@@ -3,8 +3,8 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in roar.gemspec
4
4
  gemspec
5
5
 
6
- gem "representable", "~> 2.1.0"
7
- # gem "representable", :path => "../representable"
6
+ # gem "representable", "~> 2.1.0"
7
+ gem "representable", :path => "../representable"
8
8
 
9
9
  # as long as this is not merged, i'll vendor the runner file.
10
10
  # gem "sinatra-contrib", :git => "git@github.com:apotonick/sinatra-contrib.git", :branch => "runner"
@@ -8,10 +8,16 @@ Roar is a framework for parsing and rendering REST documents. Nothing more.
8
8
 
9
9
  Representers let you define your API document structure and semantics. They allow both rendering representations from your models _and_ parsing documents to update your Ruby objects. The bi-directional nature of representers make them interesting for both server and client usage.
10
10
 
11
- Roar comes with built-in JSON, JSON-HAL, JSON-API and XML support. Its highly modulare architecture provides features like coercion, hypermedia, HTTP transport, client caching and more.
11
+ Roar comes with built-in JSON, JSON-HAL, JSON-API and XML support. Its highly modular architecture provides features like coercion, hypermedia, HTTP transport, client caching and more.
12
12
 
13
13
  Roar is completely framework-agnostic and loves being used in web kits like Rails, Webmachine, Sinatra, Padrino, etc. If you use Rails, consider [roar-rails](https://github.com/apotonick/roar-rails) for an enjoyable integration.
14
14
 
15
+ <a href="https://leanpub.com/trailblazer">
16
+ ![](https://raw.githubusercontent.com/apotonick/trailblazer/master/doc/trb.jpg)
17
+ </a>
18
+
19
+ Roar is part of the [Trailblazer project](https://github.com/apotonick/trailblazer). Please [buy the book](https://leanpub.com/trailblazer) to support the development. Several chapters will be dedicated to Roar, its integration into operations, hypermedia formats and client-side usage.
20
+
15
21
  ## Representable
16
22
 
17
23
  Roar is just a thin layer on top of the [representable](https://github.com/apotonick/representable) gem. While Roar gives you a DSL and behaviour for creating hypermedia APIs, representable implements all the mapping functionality.
@@ -235,7 +241,7 @@ We're currently [working on](https://github.com/apotonick/roar/issues/85) better
235
241
  Roar provides coercion with the [virtus](https://github.com/solnic/virtus) gem.
236
242
 
237
243
  ```ruby
238
- require 'roar/feature/coercion'
244
+ require 'roar/coercion'
239
245
 
240
246
  module SongRepresenter
241
247
  include Roar::JSON
@@ -280,7 +286,20 @@ module SongRepresenter
280
286
  end
281
287
  ```
282
288
 
283
- The `Hypermedia` feature allows declaring links using the `::link` method.
289
+ The `Hypermedia` feature allows declaring links using the `::link` method. In the block, you have access to the represented model. When using representer modules, the block is executed in the model's context.
290
+
291
+ However, when using decorators, the context is the decorator instance, allowing you to access additional data. Use `represented` to retrieve model data.
292
+
293
+ ```ruby
294
+ class SongRepresenter < Roar::Decorator
295
+ # ..
296
+ link :self do
297
+ "http://songs/#{represented.title}"
298
+ end
299
+ end
300
+ ```
301
+
302
+ This will render links into your representation.
284
303
 
285
304
  ```ruby
286
305
  song.extend(SongRepresenter)
@@ -358,6 +377,8 @@ end
358
377
 
359
378
  Documentation for HAL can be found in the [API docs](http://rdoc.info/github/apotonick/roar/Roar/Representer/JSON/HAL).
360
379
 
380
+ Make sure you [understand the different contexts](#hypermedia) for links when using decorators.
381
+
361
382
  ### Hypermedia
362
383
 
363
384
  Including the `Roar::JSON::HAL` module adds some more DSL methods to your module. It still allows using `::link` but treats them slightly different.
@@ -404,6 +425,8 @@ All HAL features in Roar are discussed in the [API docs](http://rdoc.info/github
404
425
 
405
426
  Roar also supports [JSON-API](http://jsonapi.org/) - yay! It can render _and_ parse singular and collection documents.
406
427
 
428
+ Note that you need representable >= 2.1.4 in your `Gemfile`.
429
+
407
430
  ### Resource
408
431
 
409
432
  A minimal representation can be defined as follows.
@@ -412,7 +435,7 @@ A minimal representation can be defined as follows.
412
435
  require 'roar/json/json_api'
413
436
 
414
437
  module SongsRepresenter
415
- include Roar::JSON::JsonApi
438
+ include Roar::JSON::JSONAPI
416
439
  type :songs
417
440
 
418
441
  property :id
@@ -4,7 +4,7 @@ require 'bundler'
4
4
  Bundler.setup
5
5
 
6
6
  require 'ostruct'
7
- require 'roar/representer/json'
7
+ require 'roar/json'
8
8
 
9
9
  def reset_representer(*module_name)
10
10
  module_name.each do |mod|
@@ -19,12 +19,12 @@ class Song < OpenStruct
19
19
  end
20
20
 
21
21
  module SongRepresenter
22
- include Roar::Representer::JSON
22
+ include Roar::JSON
23
23
 
24
24
  property :title
25
25
  end
26
26
 
27
- song = Song.new(title: "Fate").extend(SongRepresenter)
27
+ song = Song.new(title: 'Fate').extend(SongRepresenter)
28
28
  puts song.to_json
29
29
 
30
30
  # Parsing
@@ -40,13 +40,13 @@ require 'roar/decorator'
40
40
 
41
41
  module Decorator
42
42
  class SongRepresenter < Roar::Decorator
43
- include Roar::Representer::JSON
43
+ include Roar::JSON
44
44
 
45
45
  property :title
46
46
  end
47
47
  end
48
48
 
49
- song = Song.new(title: "Medicine Balls")
49
+ song = Song.new(title: 'Medicine Balls')
50
50
  puts Decorator::SongRepresenter.new(song).to_json
51
51
 
52
52
  # Collections
@@ -54,14 +54,14 @@ puts Decorator::SongRepresenter.new(song).to_json
54
54
  reset_representer(SongRepresenter)
55
55
 
56
56
  module SongRepresenter
57
- include Roar::Representer::JSON
57
+ include Roar::JSON
58
58
 
59
59
  property :title
60
60
  collection :composers
61
61
  end
62
62
 
63
63
 
64
- song = Song.new(title: "Roxanne", composers: ["Sting", "Stu Copeland"])
64
+ song = Song.new(title: 'Roxanne', composers: ['Sting', 'Stu Copeland'])
65
65
  song.extend(SongRepresenter)
66
66
  puts song.to_json
67
67
 
@@ -71,13 +71,13 @@ class Album < OpenStruct
71
71
  end
72
72
 
73
73
  module AlbumRepresenter
74
- include Roar::Representer::JSON
74
+ include Roar::JSON
75
75
 
76
76
  property :title
77
77
  collection :songs, extend: SongRepresenter, class: Song
78
78
  end
79
79
 
80
- album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
80
+ album = Album.new(title: 'True North', songs: [Song.new(title: 'The Island'), Song.new(:title => 'Changing Tide')])
81
81
  album.extend(AlbumRepresenter)
82
82
  puts album.to_json
83
83
 
@@ -88,12 +88,10 @@ album.from_json('{"title":"Indestructible","songs":[{"title":"Tropical London"},
88
88
 
89
89
  puts album.songs.last.inspect
90
90
 
91
- # Inline Representers # FIXME: what about collections?
92
-
93
91
  reset_representer(AlbumRepresenter)
94
92
 
95
93
  module AlbumRepresenter
96
- include Roar::Representer::JSON
94
+ include Roar::JSON
97
95
 
98
96
  property :title
99
97
 
@@ -102,12 +100,10 @@ module AlbumRepresenter
102
100
  end
103
101
  end
104
102
 
105
- album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
103
+ album = Album.new(title: 'True North', songs: [Song.new(title: 'The Island'), Song.new(:title => 'Changing Tide')])
106
104
  album.extend(AlbumRepresenter)
107
105
  puts album.to_json
108
106
 
109
-
110
-
111
107
  album = Album.new
112
108
  album.extend(AlbumRepresenter)
113
109
  album.from_json('{"title":"True North","songs":[{"title":"The Island"},{"title":"Changing Tide"}]}')
@@ -119,7 +115,7 @@ puts album.songs.first.title
119
115
  reset_representer(AlbumRepresenter)
120
116
 
121
117
  module AlbumRepresenter
122
- include Roar::Representer::JSON
118
+ include Roar::JSON
123
119
 
124
120
  property :title
125
121
 
@@ -127,13 +123,13 @@ module AlbumRepresenter
127
123
  end
128
124
 
129
125
 
130
- album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
126
+ album = Album.new(title: 'True North', songs: [Song.new(title: 'The Island'), Song.new(:title => 'Changing Tide')])
131
127
  album.extend(AlbumRepresenter)
132
128
 
133
129
  puts album.songs[0].object_id
134
130
  album.from_json('{"title":"True North","songs":[{"title":"Secret Society"},{"title":"Changing Tide"}]}')
135
131
  puts album.songs[0].title
136
- puts album.songs[0].object_id##
132
+ puts album.songs[0].object_id
137
133
 
138
134
  # Coercion, renaming, ..
139
135
 
@@ -142,8 +138,8 @@ puts album.songs[0].object_id##
142
138
  reset_representer(SongRepresenter)
143
139
 
144
140
  module SongRepresenter
145
- include Roar::Representer::JSON
146
- include Roar::Representer::Feature::Hypermedia
141
+ include Roar::JSON
142
+ include Roar::Hypermedia
147
143
 
148
144
  property :title
149
145
 
@@ -163,7 +159,7 @@ puts song.to_json
163
159
  reset_representer(SongRepresenter)
164
160
 
165
161
  module SongRepresenter
166
- include Roar::Representer::JSON
162
+ include Roar::JSON
167
163
 
168
164
  property :title
169
165
 
@@ -173,7 +169,7 @@ module SongRepresenter
173
169
  end
174
170
 
175
171
  song.extend(SongRepresenter)
176
- puts song.to_json(base_url: "localhost:3001/")
172
+ puts song.to_json(base_url: 'localhost:3001/')
177
173
 
178
174
 
179
175
  # Discovering Hypermedia
@@ -184,11 +180,11 @@ puts song.links[:self].href
184
180
 
185
181
  # Media Formats: HAL
186
182
 
187
- require 'roar/representer/json/hal'
183
+ require 'roar/json/hal'
188
184
 
189
185
  module HAL
190
186
  module SongRepresenter
191
- include Roar::Representer::JSON::HAL
187
+ include Roar::JSON::HAL
192
188
 
193
189
  property :title
194
190
 
@@ -204,7 +200,7 @@ puts song.to_json
204
200
  reset_representer(AlbumRepresenter)
205
201
 
206
202
  module AlbumRepresenter
207
- include Roar::Representer::JSON::HAL
203
+ include Roar::JSON::HAL
208
204
 
209
205
  property :title
210
206
 
@@ -213,57 +209,55 @@ module AlbumRepresenter
213
209
  end
214
210
  end
215
211
 
216
- album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
212
+ album = Album.new(title: 'True North', songs: [Song.new(title: 'The Island'), Song.new(:title => 'Changing Tide')])
217
213
  album.extend(AlbumRepresenter)
218
214
  puts album.to_json
219
215
 
220
216
  # Media Formats: JSON+Collection
221
217
 
222
- require 'roar/representer/json/collection_json'
218
+ require 'roar/json/collection_json'
223
219
 
224
220
 
225
221
  module Collection
226
222
  module SongRepresenter
227
- include Roar::Representer::JSON::CollectionJSON
228
- version "1.0"
229
- href { "http://localhost/songs/" }
223
+ include Roar::JSON::CollectionJSON
224
+ version '1.0'
225
+ href { 'http://localhost/songs/' }
230
226
 
231
227
  property :title
232
228
 
233
229
  items(:class => Song) do
234
230
  href { "//songs/#{title}" }
235
231
 
236
- property :title, :prompt => "Song title"
232
+ property :title, :prompt => 'Song title'
237
233
 
238
234
  link(:download) { "//songs/#{title}.mp3" }
239
235
  end
240
236
 
241
237
  template do
242
- property :title, :prompt => "Song title"
238
+ property :title, :prompt => 'Song title'
243
239
  end
244
240
 
245
241
  queries do
246
242
  link :search do
247
- {:href => "//search", :data => [{:name => "q", :value => ""}]}
243
+ {:href => '//search', :data => [{:name => 'q', :value => ''}]}
248
244
  end
249
245
  end
250
246
  end
251
247
  end
252
248
 
253
- song = Song.new(title: "Roxanne")
249
+ song = Song.new(title: 'Roxanne')
254
250
  song.extend(Collection::SongRepresenter)
255
251
  puts song.to_json
256
252
 
257
-
258
-
259
253
  # Client-side
260
254
  # share in gem, parse existing document.
261
255
 
262
256
  reset_representer(SongRepresenter)
263
257
 
264
258
  module SongRepresenter
265
- include Roar::Representer::JSON
266
- include Roar::Representer::Feature::Hypermedia
259
+ include Roar::JSON
260
+ include Roar::Hypermedia
267
261
 
268
262
  property :title
269
263
  property :id
@@ -274,34 +268,34 @@ module SongRepresenter
274
268
  end
275
269
 
276
270
 
277
- require 'roar/representer/feature/client'
271
+ require 'roar/client'
278
272
 
279
273
  module Client
280
274
  class Song < OpenStruct
281
- include Roar::Representer::JSON
275
+ include Roar::JSON
282
276
  include SongRepresenter
283
- include Roar::Representer::Feature::Client
277
+ include Roar::Client
284
278
  end
285
279
  end
286
280
 
287
- song = Client::Song.new(title: "Roxanne")
288
- song.post("http://localhost:4567/songs", "application/json")
281
+ song = Client::Song.new(title: 'Roxanne')
282
+ song.post(uri: 'http://localhost:4567/songs', as: 'application/json')
289
283
  puts song.id
290
284
 
291
285
 
292
286
  song = Client::Song.new
293
- song.get("http://localhost:4567/songs/1", "application/json")
287
+ song.get(uri: 'http://localhost:4567/songs/1', as: 'application/json')
294
288
  puts song.title
295
289
  puts song.links[:self].href
296
290
 
297
291
  # XML
298
292
 
299
- require 'roar/representer/xml'
293
+ require 'roar/xml'
300
294
 
301
295
  module XML
302
296
  module SongRepresenter
303
- include Roar::Representer::XML
304
- include Roar::Representer::Feature::Hypermedia
297
+ include Roar::XML
298
+ include Roar::Hypermedia
305
299
 
306
300
  property :title
307
301
  property :id
@@ -312,7 +306,7 @@ module XML
312
306
  end
313
307
  end
314
308
 
315
- song = Song.new(title: "Roxanne", id: 42)
309
+ song = Song.new(title: 'Roxanne', id: 42)
316
310
  song.extend(XML::SongRepresenter)
317
311
  puts song.to_xml
318
312
 
@@ -320,11 +314,11 @@ puts song.to_xml
320
314
 
321
315
  reset_representer(SongRepresenter)
322
316
 
323
- require 'roar/representer/feature/coercion'
317
+ require 'roar/coercion'
324
318
 
325
319
  module SongRepresenter
326
- include Roar::Representer::JSON
327
- include Roar::Representer::Feature::Coercion
320
+ include Roar::JSON
321
+ include Roar::Coercion
328
322
 
329
323
  property :title
330
324
  property :released_at, type: DateTime
@@ -342,7 +336,7 @@ class LinkOptionsCollection < Array
342
336
  end
343
337
 
344
338
  module HyperlinkiRepresenter
345
- include Roar::Representer::JSON
339
+ include Roar::JSON
346
340
 
347
341
  def to_hash(*) # setup the link
348
342
  # FIXME: why does self.to_s throw a stack level too deep (SystemStackError) ?
@@ -352,7 +346,7 @@ module HyperlinkiRepresenter
352
346
  end
353
347
 
354
348
  module Representer
355
- include Roar::Representer::JSON
349
+ include Roar::JSON
356
350
 
357
351
  def self.links
358
352
  [:self, :next]
@@ -363,8 +357,8 @@ module Representer
363
357
  def links
364
358
  # get link configurations from representable_attrs object.
365
359
  #self.representable_attrs.links
366
- LinkOptionsCollection.new(["self", "next"])
360
+ LinkOptionsCollection.new(['self', 'next'])
367
361
  end
368
362
  end
369
363
 
370
- puts "".extend(Representer).to_json
364
+ puts ''.extend(Representer).to_json
@@ -2,4 +2,4 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec path: '../'
4
4
 
5
- gem 'representable', '~> 2.1.3'
5
+ gem 'representable', '~> 2.1.5'
@@ -1,10 +1,12 @@
1
1
  require "roar/http_verbs"
2
2
 
3
3
  module Roar
4
- # Automatically add accessors for properties and collections. Also mixes in HttpVerbs.
4
+
5
+ # Mix in HttpVerbs.
5
6
  module Client
6
7
  include HttpVerbs
7
8
 
9
+ # Add accessors for properties and collections to modules.
8
10
  def self.extended(base)
9
11
  base.instance_eval do
10
12
  representable_attrs.each do |attr|