HAL+JSON generator for Ruby
Ruby
Latest commit b0cb70f Apr 8, 2015 @rivers rivers Bump version to 0.0.3
Permalink
Failed to load latest commit information.
examples
lib
spec
.gitignore
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
halogen.gemspec

README.md

Halogen

Code Climate Build Status Gem Version

This library provides a framework-agnostic interface for generating HAL+JSON representations of resources in Ruby.

Installation

Add this line to your application's Gemfile:

gem 'halogen'

And then execute:

$ bundle

Or install it yourself as:

$ gem install halogen

Usage

Basic usage

Create a simple representer class and include Halogen:

class GoatRepresenter
  include Halogen

  property :name do
    'Gideon'
  end

  link :self do
    '/goats/gideon'
  end
end

Instantiate:

repr = GoatRepresenter.new

Then call repr.render:

{
  name: 'Gideon',
  _links: {
    self: { href: '/goats/gideon' }
  }
}

Or repr.to_json:

'{"name": "Gideon", "_links": {"self": {"href": "/goats/gideon"}}}'

Representer types

1. Simple

Not associated with any particular resource or collection. For example, an API entry point:

class ApiRootRepresenter
  include Halogen

  link(:self) { '/api' }
end

2. Resource

Represents a single item:

class GoatRepresenter
  include Halogen

  resource :goat
end

When a resource is declared, #initialize expects the resource as the first argument:

repr = GoatRepresenter.new(Goat.new, ...)

This makes property definitions cleaner:

property :name # now calls Goat#name by default

3. Collection

Represents a collection of items. When a collection is declared, the embedded resource with the same name will always be embedded, whether it is requested via standard embed options or not.

class GoatKidsRepresenter
  include Halogen

  collection :kids

  embed(:kids) { ... } # always embedded
end

Defining properties, links and embeds

Properties can be defined in several ways:

property(:age) { "#{goat.age} years old" }
property :age # => Goat#age, if resource is declared
property :age do
  goat.age.round
end
property(:age) { calculate_age }

def calculate_age
  ...
end

Conditionals

The inclusion of properties can be determined by conditionals using if and unless options. For example, with a method name:

property :age, if: :include_age?

def include_age?
  goat.age < 10
end

With a proc:

property :age, unless: proc { goat.age.nil? }, value: ...

For links and embeds:

link :kids, :templated, unless: :exclude_kids_link?, value: ...
embed :kids, if: proc { goat.kids.size > 0 } do
  ...
end

Links

Simple link:

link(:root) { '/' }
# => { _links: { root: { href: '/' } } ... }

Templated link:

link(:find, :templated) { '/goats/{?id}' }
# => { _links: { find: { href: '/goats/{?id}', templated: true } } ... }

Embedded resources

Embedded resources are not rendered by default. They will be included if both of the following conditions are met:

  1. The proc returns either a Halogen instance or an array of Halogen instances
  2. The embed is requested via the parent representer's options, e.g.:
GoatRepresenter.new(embed: { kids: true, parents: false })

Embedded resources can be nested to any depth, e.g.:

GoatRepresenter.new(embed: {
  kids: {
    foods: {
      ingredients: true
    },
    pasture: true
  }
})

Using with Rails

If Halogen is loaded in a Rails application, Rails url helpers will be available in representers:

link(:new) { new_goat_url }

More examples

What's with the goat?

It is majestic.

Contributing

  1. Fork it ( https://github.com/mode/halogen/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request