roar 0.12.9 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +8 -10
- data/CHANGES.markdown +24 -2
- data/Gemfile +5 -2
- data/README.markdown +132 -28
- data/TODO.markdown +9 -7
- data/examples/example.rb +2 -0
- data/examples/example_server.rb +19 -3
- data/gemfiles/Gemfile.representable-2.0 +5 -0
- data/gemfiles/Gemfile.representable-2.1 +5 -0
- data/lib/roar.rb +1 -1
- data/lib/roar/client.rb +38 -0
- data/lib/roar/{representer/feature/coercion.rb → coercion.rb} +2 -1
- data/lib/roar/decorator.rb +3 -11
- data/lib/roar/http_verbs.rb +88 -0
- data/lib/roar/hypermedia.rb +174 -0
- data/lib/roar/json.rb +55 -0
- data/lib/roar/json/collection.rb +3 -0
- data/lib/roar/{representer/json → json}/collection_json.rb +20 -20
- data/lib/roar/{representer/json → json}/hal.rb +33 -31
- data/lib/roar/json/hash.rb +3 -0
- data/lib/roar/json/json_api.rb +208 -0
- data/lib/roar/representer.rb +3 -36
- data/lib/roar/transport/faraday.rb +49 -0
- data/lib/roar/transport/net_http.rb +57 -0
- data/lib/roar/transport/net_http/request.rb +72 -0
- data/lib/roar/version.rb +1 -1
- data/lib/roar/xml.rb +54 -0
- data/roar.gemspec +5 -4
- data/test/client_test.rb +3 -3
- data/test/coercion_feature_test.rb +6 -3
- data/test/collection_json_test.rb +8 -10
- data/test/decorator_test.rb +27 -15
- data/test/faraday_http_transport_test.rb +13 -15
- data/test/hal_json_test.rb +16 -16
- data/test/hal_links_test.rb +3 -3
- data/test/http_verbs_test.rb +17 -22
- data/test/hypermedia_feature_test.rb +23 -45
- data/test/hypermedia_test.rb +11 -23
- data/test/integration/band_representer.rb +2 -2
- data/test/integration/runner.rb +4 -3
- data/test/integration/server.rb +13 -2
- data/test/integration/ssl_server.rb +1 -1
- data/test/json_api_test.rb +336 -0
- data/test/json_representer_test.rb +16 -12
- data/test/lib/runner.rb +134 -0
- data/test/lonely_test.rb +9 -0
- data/test/net_http_transport_test.rb +4 -4
- data/test/representer_test.rb +2 -2
- data/test/{lib/roar/representer/transport/net_http/request_test.rb → ssl_client_certs_test.rb} +43 -5
- data/test/test_helper.rb +12 -5
- data/test/xml_representer_test.rb +26 -166
- metadata +49 -29
- data/gemfiles/Gemfile.representable-1.7 +0 -6
- data/gemfiles/Gemfile.representable-1.8 +0 -6
- data/lib/roar/representer/feature/client.rb +0 -39
- data/lib/roar/representer/feature/http_verbs.rb +0 -95
- data/lib/roar/representer/feature/hypermedia.rb +0 -175
- data/lib/roar/representer/json.rb +0 -67
- data/lib/roar/representer/transport/faraday.rb +0 -50
- data/lib/roar/representer/transport/net_http.rb +0 -59
- data/lib/roar/representer/transport/net_http/request.rb +0 -75
- data/lib/roar/representer/xml.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52b7f8314b58e3ebc06ca5dde920c82d8584b16b
|
4
|
+
data.tar.gz: 005bfc57c05c3a67ed3d7f1a778f1052c5d087c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c06fc967e1c3f389e4ad87a144c78b516fc32267dea3bd0d5bacd99b7cc3e102faadeaec32c06dc4887526e74b95b745452210d13042aff727bd238f127f8f4
|
7
|
+
data.tar.gz: 497ac335d8ad6d65df546e8bff9e3c148fd204872d608a48580dce62334f082838f9e213cbaec7dd2c38b2c822073a661796e0c1eae3ebb04206a5a1778262c8
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
- rvm: 2.0.0
|
10
|
-
gemfile: gemfiles/Gemfile.representable-1.8
|
1
|
+
rvm:
|
2
|
+
- 1.9.3
|
3
|
+
- 2.0.0
|
4
|
+
- 2.1
|
5
|
+
- 2.2
|
6
|
+
gemfiles:
|
7
|
+
- gemfiles/Gemfile.representable-2.0
|
8
|
+
- gemfiles/Gemfile.representable-2.1
|
11
9
|
notifications:
|
12
10
|
irc: "irc.freenode.org#cells"
|
data/CHANGES.markdown
CHANGED
@@ -1,6 +1,28 @@
|
|
1
|
-
# 0.
|
1
|
+
# 1.0.0
|
2
2
|
|
3
|
-
|
3
|
+
## Breakage
|
4
|
+
|
5
|
+
* Removed `Representer` and `Feature` namespace. That means changes along the following.
|
6
|
+
* `Roar::Representer::Feature::Hypermedia` --> `Roar::Hypermedia`
|
7
|
+
* `Roar::Representer::JSON` --> `Roar::JSON`
|
8
|
+
* Removed positional arguments for `HttpVerbs#get` and friends.
|
9
|
+
|
10
|
+
## Added
|
11
|
+
|
12
|
+
* `Roar::JSON::JsonApi` supports JSON-API. A big thanks to @oliverbarnes for his continous help, support and research on how to implement this standard.
|
13
|
+
|
14
|
+
|
15
|
+
## Relevant
|
16
|
+
|
17
|
+
* `Hyperlink#to_hash` now returns stringified keys.
|
18
|
+
* Removed `Representer#before_serialize` hook. Override `#serialize` yourself.
|
19
|
+
* Represented#links now returns `nil` when no parsing has happened.
|
20
|
+
* Removed class methods `::from_json`, `::from_hash`, `::from_xml` and `::deserialize`. Please build the instance yourself and use something along `Song.new.from_json`.
|
21
|
+
|
22
|
+
## Internals
|
23
|
+
|
24
|
+
* Remove the concept of ´links_array`. `Hyperlink` instances for rendering or that have been parsed are always stored in a `LinkCollection` that is available via `#links`.
|
25
|
+
* `Hypermedia` is now 43% simpler.
|
4
26
|
|
5
27
|
# 0.12.8
|
6
28
|
|
data/Gemfile
CHANGED
@@ -3,5 +3,8 @@ source "http://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in roar.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
gem "
|
6
|
+
gem "representable", "~> 2.1.0"
|
7
|
+
# gem "representable", :path => "../representable"
|
8
|
+
|
9
|
+
# as long as this is not merged, i'll vendor the runner file.
|
10
|
+
# gem "sinatra-contrib", :git => "git@github.com:apotonick/sinatra-contrib.git", :branch => "runner"
|
data/README.markdown
CHANGED
@@ -8,7 +8,7 @@ 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 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 modulare 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
|
|
@@ -24,10 +24,10 @@ If in need for a feature, make sure to check the [representable API docs](https:
|
|
24
24
|
Let's see how representers work. They're fun to use.
|
25
25
|
|
26
26
|
```ruby
|
27
|
-
require 'roar/
|
27
|
+
require 'roar/json'
|
28
28
|
|
29
29
|
module SongRepresenter
|
30
|
-
include Roar::
|
30
|
+
include Roar::JSON
|
31
31
|
|
32
32
|
property :title
|
33
33
|
end
|
@@ -81,7 +81,7 @@ Many people dislike `#extend` due to eventual performance issue or object pollut
|
|
81
81
|
require 'roar/decorator'
|
82
82
|
|
83
83
|
class SongRepresenter < Roar::Decorator
|
84
|
-
include Roar::
|
84
|
+
include Roar::JSON
|
85
85
|
|
86
86
|
property :title
|
87
87
|
end
|
@@ -107,7 +107,7 @@ Roar (or rather representable) also allows to map collections in documents.
|
|
107
107
|
|
108
108
|
```ruby
|
109
109
|
module SongRepresenter
|
110
|
-
include Roar::
|
110
|
+
include Roar::JSON
|
111
111
|
|
112
112
|
property :title
|
113
113
|
collection :composers
|
@@ -140,7 +140,7 @@ Another representer to represent.
|
|
140
140
|
|
141
141
|
```ruby
|
142
142
|
module AlbumRepresenter
|
143
|
-
include Roar::
|
143
|
+
include Roar::JSON
|
144
144
|
|
145
145
|
property :title
|
146
146
|
collection :songs, extend: SongRepresenter, class: Song
|
@@ -188,7 +188,7 @@ Sometimes you don't wanna create two separate representers - although it makes t
|
|
188
188
|
|
189
189
|
```ruby
|
190
190
|
module AlbumRepresenter
|
191
|
-
include Roar::
|
191
|
+
include Roar::JSON
|
192
192
|
|
193
193
|
property :title
|
194
194
|
|
@@ -207,7 +207,7 @@ Usually, when parsing, nested objects are created from scratch. If you want nest
|
|
207
207
|
|
208
208
|
```ruby
|
209
209
|
module AlbumRepresenter
|
210
|
-
include Roar::
|
210
|
+
include Roar::JSON
|
211
211
|
|
212
212
|
property :title
|
213
213
|
|
@@ -235,11 +235,11 @@ We're currently [working on](https://github.com/apotonick/roar/issues/85) better
|
|
235
235
|
Roar provides coercion with the [virtus](https://github.com/solnic/virtus) gem.
|
236
236
|
|
237
237
|
```ruby
|
238
|
-
require 'roar/
|
238
|
+
require 'roar/feature/coercion'
|
239
239
|
|
240
240
|
module SongRepresenter
|
241
|
-
include Roar::
|
242
|
-
include Roar::
|
241
|
+
include Roar::JSON
|
242
|
+
include Roar::Coercion
|
243
243
|
|
244
244
|
property :title
|
245
245
|
property :released_at, type: DateTime
|
@@ -269,8 +269,8 @@ Roar comes with built-in support for embedding and processing hypermedia in your
|
|
269
269
|
|
270
270
|
```ruby
|
271
271
|
module SongRepresenter
|
272
|
-
include Roar::
|
273
|
-
include Roar::
|
272
|
+
include Roar::JSON
|
273
|
+
include Roar::Hypermedia
|
274
274
|
|
275
275
|
property :title
|
276
276
|
|
@@ -298,7 +298,7 @@ Sometimes you need more data in the link block. Data that's not available from t
|
|
298
298
|
|
299
299
|
```ruby
|
300
300
|
module SongRepresenter
|
301
|
-
include Roar::
|
301
|
+
include Roar::JSON
|
302
302
|
|
303
303
|
property :title
|
304
304
|
|
@@ -343,10 +343,10 @@ Simply by including a module you make your representer understand the media type
|
|
343
343
|
The [HAL](http://stateless.co/hal_specification.html) format is a simple media type that defines embedded resources and hypermedia.
|
344
344
|
|
345
345
|
```ruby
|
346
|
-
require 'roar/
|
346
|
+
require 'roar/json/hal'
|
347
347
|
|
348
348
|
module SongRepresenter
|
349
|
-
include Roar::
|
349
|
+
include Roar::JSON::HAL
|
350
350
|
|
351
351
|
property :title
|
352
352
|
|
@@ -360,7 +360,7 @@ Documentation for HAL can be found in the [API docs](http://rdoc.info/github/apo
|
|
360
360
|
|
361
361
|
### Hypermedia
|
362
362
|
|
363
|
-
Including the `Roar::
|
363
|
+
Including the `Roar::JSON::HAL` module adds some more DSL methods to your module. It still allows using `::link` but treats them slightly different.
|
364
364
|
|
365
365
|
```ruby
|
366
366
|
song.to_json
|
@@ -377,7 +377,7 @@ Nested, or embedded, resources can be defined using the `:embedded` option.
|
|
377
377
|
|
378
378
|
```ruby
|
379
379
|
module AlbumRepresenter
|
380
|
-
include Roar::
|
380
|
+
include Roar::JSON::HAL
|
381
381
|
|
382
382
|
property :title
|
383
383
|
|
@@ -397,7 +397,97 @@ album.to_json
|
|
397
397
|
|
398
398
|
HAL keys nested resources under the `_embedded` key and then by their type.
|
399
399
|
|
400
|
-
All HAL features in Roar are discussed in the [API docs](http://rdoc.info/github/apotonick/roar/Roar/Representer/JSON/HAL), including [array links](https://github.com/apotonick/roar/blob/master/lib/roar/
|
400
|
+
All HAL features in Roar are discussed in the [API docs](http://rdoc.info/github/apotonick/roar/Roar/Representer/JSON/HAL), including [array links](https://github.com/apotonick/roar/blob/master/lib/roar/json/hal.rb#L176).
|
401
|
+
|
402
|
+
|
403
|
+
## JSON-API
|
404
|
+
|
405
|
+
Roar also supports [JSON-API](http://jsonapi.org/) - yay! It can render _and_ parse singular and collection documents.
|
406
|
+
|
407
|
+
### Resource
|
408
|
+
|
409
|
+
A minimal representation can be defined as follows.
|
410
|
+
|
411
|
+
```ruby
|
412
|
+
require 'roar/json/json_api'
|
413
|
+
|
414
|
+
module SongsRepresenter
|
415
|
+
include Roar::JSON::JsonApi
|
416
|
+
type :songs
|
417
|
+
|
418
|
+
property :id
|
419
|
+
property :title
|
420
|
+
end
|
421
|
+
```
|
422
|
+
|
423
|
+
Properties of the represented model are defined in the root level.
|
424
|
+
|
425
|
+
### Hypermedia
|
426
|
+
|
427
|
+
You can add links to `linked` models within the resource section.
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
module SongsRepresenter
|
431
|
+
# ...
|
432
|
+
|
433
|
+
has_one :composer
|
434
|
+
has_many :listeners
|
435
|
+
end
|
436
|
+
```
|
437
|
+
|
438
|
+
Global `links` can be added using the familiar `::link` method (this is still WIP as the DSL is not final).
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
module SongsRepresenter
|
442
|
+
# ...
|
443
|
+
|
444
|
+
link "songs.album" do
|
445
|
+
{
|
446
|
+
type: "album",
|
447
|
+
href: "http://example.com/albums/{songs.album}"
|
448
|
+
}
|
449
|
+
end
|
450
|
+
end
|
451
|
+
```
|
452
|
+
|
453
|
+
### Compounds
|
454
|
+
|
455
|
+
To add compound models into the document, use `::compound`.
|
456
|
+
|
457
|
+
```ruby
|
458
|
+
module SongsRepresenter
|
459
|
+
# ...
|
460
|
+
|
461
|
+
compound do
|
462
|
+
property :album do
|
463
|
+
property :id
|
464
|
+
property :title
|
465
|
+
end
|
466
|
+
|
467
|
+
collection :musicians do
|
468
|
+
property :name
|
469
|
+
end
|
470
|
+
end
|
471
|
+
```
|
472
|
+
|
473
|
+
### Usage
|
474
|
+
|
475
|
+
As JSON-API per definition can represent singular models and collections you have two entry points.
|
476
|
+
|
477
|
+
```ruby
|
478
|
+
SongsRepresenter.prepare(Song.find(1)).to_json
|
479
|
+
SongsRepresenter.prepare(Song.new).from_json("..")
|
480
|
+
```
|
481
|
+
|
482
|
+
Singular models can use the representer module directly.
|
483
|
+
|
484
|
+
```ruby
|
485
|
+
SongsRepresenter.for_collection.prepare([Song.find(1), Song.find(2)]).to_json
|
486
|
+
SongsRepresenter.for_collection.prepare([Song.new, Song.new]).from_json("..")
|
487
|
+
```
|
488
|
+
|
489
|
+
|
490
|
+
Parsing currently works great with singular documents - for collections, we are still working out how to encode the application semantics. Feel free to help.
|
401
491
|
|
402
492
|
|
403
493
|
## Collection+JSON
|
@@ -406,7 +496,7 @@ The [Collection+JSON media format](http://amundsen.com/media-types/collection/)
|
|
406
496
|
|
407
497
|
```ruby
|
408
498
|
module SongRepresenter
|
409
|
-
include Roar::
|
499
|
+
include Roar::JSON::CollectionJSON
|
410
500
|
version "1.0"
|
411
501
|
href { "http://localhost/songs/" }
|
412
502
|
|
@@ -455,8 +545,8 @@ Consider the following shared representer.
|
|
455
545
|
|
456
546
|
```ruby
|
457
547
|
module SongRepresenter
|
458
|
-
include Roar::
|
459
|
-
include Roar::
|
548
|
+
include Roar::JSON
|
549
|
+
include Roar::Hypermedia
|
460
550
|
|
461
551
|
property :title
|
462
552
|
property :id
|
@@ -470,18 +560,18 @@ end
|
|
470
560
|
In a client where you don't have access to the database it is common to use `OpenStruct` classes as domain objects.
|
471
561
|
|
472
562
|
```ruby
|
473
|
-
require 'roar/
|
563
|
+
require 'roar/client'
|
474
564
|
|
475
565
|
class Song < OpenStruct
|
476
|
-
include Roar::
|
566
|
+
include Roar::JSON
|
477
567
|
include SongRepresenter
|
478
|
-
include Roar::
|
568
|
+
include Roar::Client
|
479
569
|
end
|
480
570
|
```
|
481
571
|
|
482
572
|
## HTTP Support
|
483
573
|
|
484
|
-
The `
|
574
|
+
The `Client` module mixes all necessary methods into the client class, e.g. it provides HTTP support
|
485
575
|
|
486
576
|
```ruby
|
487
577
|
song = Song.new(title: "Roxanne")
|
@@ -525,8 +615,22 @@ The HTTP verbs allow you to specify credentials for HTTP basic auth.
|
|
525
615
|
|
526
616
|
```ruby
|
527
617
|
song.get(uri: "http://localhost:4567/songs/1", basic_auth: ["username", "secret_password"])
|
618
|
+
|
528
619
|
```
|
529
620
|
|
621
|
+
### Client SSL certificates
|
622
|
+
|
623
|
+
(Only currently supported with Net:Http)
|
624
|
+
|
625
|
+
```ruby
|
626
|
+
song.get(uri: "http://localhost:4567/songs/1", pem_file: "/path/to/client/cert.pem", ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER)
|
627
|
+
|
628
|
+
```
|
629
|
+
|
630
|
+
Note: ssl_verify_mode is not required and will default to ```OpenSSL::SSL::VERIFY_PEER)```
|
631
|
+
|
632
|
+
|
633
|
+
|
530
634
|
### Request customization
|
531
635
|
|
532
636
|
All verbs yield the request object before the request is sent, allowing to modify it. It is a `Net::HTTP::Request` instance (unless you use Faraday).
|
@@ -544,7 +648,7 @@ Roar also comes with XML support.
|
|
544
648
|
```ruby
|
545
649
|
module SongRepresenter
|
546
650
|
include Roar::Representer::XML
|
547
|
-
include Roar::Representer::
|
651
|
+
include Roar::Representer::Hypermedia
|
548
652
|
|
549
653
|
property :title
|
550
654
|
property :id
|
@@ -584,4 +688,4 @@ We also have a [mailing list](https://groups.google.com/forum/?fromgroups#!forum
|
|
584
688
|
|
585
689
|
## License
|
586
690
|
|
587
|
-
Roar is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
691
|
+
Roar is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
data/TODO.markdown
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# 1.0
|
2
|
+
|
3
|
+
* merge client errors request
|
4
|
+
* simpler link for JSON-API?
|
5
|
+
* remove HttpVerbs deprecations
|
6
|
+
|
7
|
+
* Hyperlink representers => decrators. test hash representer with decorator (rpr)
|
8
|
+
|
9
|
+
|
1
10
|
* Add proxies, so nested models can be lazy-loaded.
|
2
11
|
* move #prepare_links! call to #_links or something so it doesn't need to be called in #serialize.
|
3
|
-
* alias Roar::Representer to Representer
|
4
|
-
* remove #before_serialize and just overwrite #serialize
|
5
12
|
* abstract ::links_definition_options and move them out of the generic representers (JSON, XML).
|
6
|
-
* make 1.8 tests work, again (hash ordering!)
|
7
|
-
|
8
|
-
* release 1.0
|
9
|
-
* representable 1.8, only.
|
10
|
-
* revise Hypermedia
|
11
13
|
* work on HAL-Object
|
data/examples/example.rb
CHANGED
data/examples/example_server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require "bundler/setup"
|
2
4
|
require "sinatra"
|
3
5
|
require "ostruct"
|
@@ -9,10 +11,24 @@ get "/method" do
|
|
9
11
|
end
|
10
12
|
|
11
13
|
post "/songs" do
|
12
|
-
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
|
14
|
+
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
|
13
15
|
end
|
14
16
|
|
15
17
|
|
16
18
|
get "/songs/1" do
|
17
|
-
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
|
18
|
-
end
|
19
|
+
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
|
20
|
+
end
|
21
|
+
|
22
|
+
post "/respond404" do
|
23
|
+
status 404
|
24
|
+
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}],"revision":"2"}'
|
25
|
+
end
|
26
|
+
|
27
|
+
post "/respond407" do
|
28
|
+
status 407
|
29
|
+
end
|
30
|
+
|
31
|
+
get "/respond200" do
|
32
|
+
status 200
|
33
|
+
'{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"},"revision":"3"]}'
|
34
|
+
end
|