yaks 0.8.1 → 0.8.2

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: 2e248248443677439e3a74cc66a1dc5a71977094
4
- data.tar.gz: b8fb999606b2675d964eb93fa00c4e2f447741db
3
+ metadata.gz: 2011212cb9c579cebb6ee58228407bdfde224829
4
+ data.tar.gz: 96d967888e80337c38850db63923bac9a74446e9
5
5
  SHA512:
6
- metadata.gz: 81021221514f434b2e412f7b1cd894d0fe3e134a2adc5f4dfae727473bfaca130372ca7409b2a795aa47e626ee700068351d59587972cd2ff4ebdcc6b44f2d31
7
- data.tar.gz: bef8b36b5b9815bd4275fd2ce2a182a4c191f718ba1967ba91338b9f133fdb0b6c969e63d4040177f6d81c88192164ddad8a7c73064a96edf6163d2fc3a62458
6
+ metadata.gz: f6aa331742aabedbf57d46182d72029664f385af6d844bc92b1180e3aa8d0e956782deab1d2406ef8cebac36dbbea57189675a6d558d992dae6f37fd1bf12ad6
7
+ data.tar.gz: c53bec9f2219b58e7f2d6cd16b0966ec1ceeadc9507556c21569746e753e43fa6e65e7bd099f2b6cbe6d5943476824eea28ec6118beeffbef1665e5bb210cb9e
data/README.md CHANGED
@@ -37,8 +37,7 @@ supporting hypermedia formats in Ruby.
37
37
  Yaks can be used in production today, as we do, but until 1.0 is
38
38
  released there will regularly be breaking changes, as we figure out
39
39
  the best way to do things. These are all documented clearly in the
40
- [changelog](/CHANGELOG.md). At this point we recommend locking to an
41
- exact version number.
40
+ [changelog](/CHANGELOG.md).
42
41
 
43
42
  ## Concepts
44
43
 
@@ -301,9 +300,14 @@ class FooMapper
301
300
  end
302
301
  ```
303
302
 
304
- The env hash will be available to all mappers, so you can use this to pass around context. In particular context related to the current HTTP request, e.g. the current logged in user, which is why the recommended use is to pass in the Rack environment.
303
+ The env hash will be available to all mappers, so you can use this to
304
+ pass around context. In particular context related to the current HTTP
305
+ request, e.g. the current logged in user, which is why the recommended
306
+ use is to pass in the Rack environment.
305
307
 
306
- If `env` contains a `HTTP_ACCEPT` key (Rack's way of representing the `Accept` header), Yaks will return the format that most closely matches what was requested.
308
+ If `env` contains a `HTTP_ACCEPT` key (Rack's way of representing the
309
+ `Accept` header), Yaks will return the format that most closely
310
+ matches what was requested.
307
311
 
308
312
  ## Namespace
309
313
 
@@ -385,23 +389,43 @@ class ErrorMapper < Yaks::Mapper
385
389
  end
386
390
  ```
387
391
 
388
- ## Resources and Serializers
392
+ ## Resources, Formatters, Serializers
389
393
 
390
- Yaks uses an intermediate "Resource" representation to support multiple output formats. A mapper turns a domain model into a `Yaks::Resource`. A serializer (e.g. `Yaks::Serializer::Hal`) takes the resource and outputs the structure of the target format.
394
+ Yaks uses an intermediate "Resource" representation to support
395
+ multiple output formats. A mapper turns a domain model into a
396
+ `Yaks::Resource`. A formatter (e.g. `Yaks::Format::Hal`) takes
397
+ the resource and outputs the structure of the target format.
391
398
 
392
- Since version 0.4 the recommended API is through `Yaks.new {...}.serialize`. This will give you back a composite value consisting of primitives that have a mapping to JSON, so you can use your favorite JSON encoder to turn this into a character stream.
399
+ Finally a serializer will take this document structure and turn it
400
+ into a string. For JSON documents the intermediate format consists of
401
+ Ruby primitives like arrays and hashes. HTML/XML based formats on the
402
+ other hand return a [Hexp::Node](https://github.com/plexus/hexp).
393
403
 
394
- ```ruby
395
- my_yaks = Yaks.new
396
- hal = my_yaks.call(model)
397
- puts JSON.dump(hal)
398
- ```
404
+ For JSON based format there's an extra step between `format` and
405
+ `serialize` called `primitivize`, this way Ruby objects which don't
406
+ have an equivalent in the JSON spec, like `Symbol` or `Date`, can be
407
+ turned into objects that are representable in JSON. See
408
+ [Primitiver](#primitivizer).
409
+
410
+ ## Formats
399
411
 
400
- There are at least a handful of JSON libraries and implementations for Ruby out there, with different trade-offs. Yaks does not impose an opinion on which one to use
412
+ Below follows a brief overview of formats that are available in
413
+ Yaks. The maturity of these formats varies, since we depend on people
414
+ that use a certain format actively to contribute. Implementing formats
415
+ is in generally straightforward, and consists mostly of deciding how
416
+ the attributes, links, forms, of a `Yaks::Resource` should be
417
+ represented. Depending on the format this might be a subject for
418
+ debate. We welcome these discussions, and if your opinion differs from
419
+ what ends up in Yaks, it should be trivial to change these
420
+ representations for your use case.
401
421
 
402
422
  ### HAL
403
423
 
404
- This is the default. In HAL one decides when building an API which links can only be singular (e.g. self), and which are always represented as an array. Yaks defaults to singular as I've found it to be the most common case. If you want specific links to be plural, then configure their rel href as such.
424
+ This is the default. In HAL one decides when building an API which
425
+ links can only be singular (e.g. self), and which are always
426
+ represented as an array. Yaks defaults to singular as I've found it to
427
+ be the most common case. If you want specific links to be plural, then
428
+ configure their rel href as such.
405
429
 
406
430
  ```ruby
407
431
  hal = Yaks.new do
@@ -409,17 +433,43 @@ hal = Yaks.new do
409
433
  end
410
434
  ```
411
435
 
412
- CURIEs are not explicitly supported (yet), but it's possible to use them with some effort, see `examples/hal01.rb` for an example.
436
+ CURIEs are not explicitly supported (yet), but it's possible to use
437
+ them with some manual effort.
438
+
439
+ The line between a singular resource and a collection is fuzzy in
440
+ HAL. To stick close to the spec you're best to create your own
441
+ singular types that represent collections, rather than rendering a top
442
+ level CollectionResource.
443
+
444
+ ### HTML
445
+
446
+ The hypermedia format *par excellence*. Yaks can generate a version of
447
+ your API, including links and forms, that is usable straight from a
448
+ standard web browser. This allows API interactions to be developed and
449
+ tested independent from any client application.
413
450
 
414
- The line between a singular resource and a collection is fuzzy in HAL. To stick close to the spec you're best to create your own singular types that represent collections, rather than rendering a top level CollectionResource.
451
+ If you let Yaks handle your content type negotiation (i.e. pass it the
452
+ rack env, and honour the content type it detects, see
453
+ [integration](#integration), simply opening a browser and pointing it
454
+ at your API entry point should do the trick.
415
455
 
416
456
  ### JSON-API
417
457
 
458
+ The JSON-API spec has evolved since the Yaks formatter was
459
+ implemented. It is also not the most suitable format for Yaks
460
+ feature-set due to its strong convention-driven nature and weak
461
+ support for hypermedia.
462
+
463
+ If you would like to see better JSON-API support, get in touch. We
464
+ might be able to work something out.
465
+
418
466
  ```ruby
419
467
  default_format :json_api
420
468
  ```
421
469
 
422
- JSON-API has no concept of outbound links, so these will not be rendered. Instead the key will be inferred from the mapper class name by default. This can be changed per mapper:
470
+ JSON-API has no concept of outbound links, so these will not be
471
+ rendered. Instead the key will be inferred from the mapper class name
472
+ by default. This can be changed per mapper:
423
473
 
424
474
  ```ruby
425
475
  class AnimalMapper
@@ -524,7 +574,9 @@ yaks = Yaks.new do
524
574
  end
525
575
  ```
526
576
 
527
- ## Primitives
577
+ <a id="primitivizer">
578
+
579
+ ## Primitivizer
528
580
 
529
581
  For JSON based formats, the "syntax tree" is merely a structure of Ruby primitives that have a JSON equivalent. If your mappers return non-primitive attribute values, you can define how they should be converted. For example, JSON has no notion of dates. If your mappers return these types as attributes, then Yaks needs to know how to turn these into primitives. To add extra types, use `map_to_primitive`
530
582
 
@@ -550,6 +602,38 @@ end
550
602
 
551
603
  Yaks by default "primitivizes" symbols (as strings), and classes that include Enumerable (as arrays).
552
604
 
605
+
606
+ <a id="integration">
607
+
608
+ ## Integration
609
+
610
+ It is recommended to let Yaks handle the negotiation of media types,
611
+ so that consumer can request the format they prefer using an `Accept:`
612
+ header. To do this requires two steps: first make sure you pass the
613
+ rack env to Yaks, this way it will detect any `Accept` header and
614
+ honor it. While this is enough to get the correct serialized output,
615
+ it will likely be served up with the wrong `Content-Type` header by
616
+ your web framework.
617
+
618
+ To fix this, ask Yaks first for the "runner" for a given input, then
619
+ get the media type and serialized resource from the runner.
620
+
621
+ ```ruby
622
+ # Tell your web framework about the supported formats
623
+ Yaks::Format.all.each do |format|
624
+ mime_type format.format_name, format.media_type
625
+ end
626
+
627
+ # one time Yaks configuration
628
+ yaks = Yaks.new {...}
629
+
630
+ # on each request
631
+ runner = yaks.runner(object, env: rack_env)
632
+ format = runner.format_name
633
+ output = runner.call
634
+ ```
635
+
636
+
553
637
  ## Real World Usage
554
638
 
555
639
  Yaks is used in production by [Ticketsolve](http://www.ticketsolve.com/). You can find an example API endpoint [here](http://leicestersquaretheatre.ticketsolve.com/api).
data/lib/yaks/format.rb CHANGED
@@ -8,6 +8,8 @@ module Yaks
8
8
  # @return [Hash]
9
9
  attr_reader :options
10
10
 
11
+ attr_reader :env
12
+
11
13
  def_delegators :resource, :links, :attributes, :subresources
12
14
 
13
15
  protected :links, :attributes, :subresources, :options
@@ -20,7 +22,8 @@ module Yaks
20
22
 
21
23
  # @param [Yaks::Resource] resource
22
24
  # @return [Hash]
23
- def call(resource, _env = {})
25
+ def call(resource, env = {})
26
+ @env = env
24
27
  serialize_resource(resource)
25
28
  end
26
29
  alias serialize call
data/lib/yaks/runner.rb CHANGED
@@ -41,7 +41,7 @@ module Yaks
41
41
  Format.by_name(options.fetch(:format) { default_format })
42
42
  }
43
43
  end
44
- memoize :format_class
44
+ memoize :format_class, freezer: :noop
45
45
 
46
46
  def steps
47
47
  [[ :map, mapper ],
@@ -61,7 +61,7 @@ module Yaks
61
61
  def formatter
62
62
  format_class.new(format_options_hash[format_name])
63
63
  end
64
- memoize :formatter
64
+ memoize :formatter, freezer: :noop
65
65
 
66
66
  def primitivizer
67
67
  proc do |input|
@@ -77,7 +77,7 @@ module Yaks
77
77
  def serializer
78
78
  serializers.fetch(format_class.serializer)
79
79
  end
80
- memoize :serializer
80
+ memoize :serializer, freezer: :noop
81
81
 
82
82
  def hooks
83
83
  config.hooks + options.fetch(:hooks, [])
data/lib/yaks/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yaks
2
- VERSION = '0.8.1'
2
+ VERSION = '0.8.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arne Brasseur
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-20 00:00:00.000000000 Z
11
+ date: 2015-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inflection