roar 0.12.9 → 1.0.0.beta1
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/.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
|