Skip to content

Commit

Permalink
Use Roar with Grape proof of concept.
Browse files Browse the repository at this point in the history
  • Loading branch information
dblock committed Dec 24, 2012
0 parents commit 5f81f3c
Show file tree
Hide file tree
Showing 19 changed files with 308 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
Gemfile.lock
doc
pkg
3 changes: 3 additions & 0 deletions .rspec
@@ -0,0 +1,3 @@
--color
--format=documentation

4 changes: 4 additions & 0 deletions .travis.yml
@@ -0,0 +1,4 @@
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
14 changes: 14 additions & 0 deletions Gemfile
@@ -0,0 +1,14 @@
source 'https://rubygems.org'

gemspec

gem "grape", :git => "git://github.com/intridea/grape.git"

group :development do
gem "rake"
end

group :test do
gem "rspec"
gem "rack-test"
end
22 changes: 22 additions & 0 deletions LICENSE
@@ -0,0 +1,22 @@
MIT License

Copyright (c) 2012 Daniel Doubrovkine, Art.sy Inc.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 changes: 52 additions & 0 deletions README.md
@@ -0,0 +1,52 @@
Grape::Roar
------------

A proof of concept for using Roar[https://github.com/apotonick/roar] in [Grape](https://github.com/intridea/grape). This implementation doesn't do anything - Grape works with Roar out of the box, call `to_json` on representers.

[![Build Status](https://secure.travis-ci.org/dblock/grape-roar.png)](http://travis-ci.org/dblock/grape-roar)

Installation
------------

Add the `grape`, `roar` and `grape-roar` gems to Gemfile. Currently requires HEAD of Grape.

```ruby
gem 'grape', :git => "https://github.com/intridea/grape.git"
gem 'roar'
gem 'grape-roar'
```

And then execute:

$ bundle

Usage
-----

### Require grape-roar

```ruby
# config.ru
require 'grape/roar'
```

### Tell your API to use Grape::Formatter::Roar

```ruby
class API < Grape::API
format :json
formatter :json, Grape::Formatter::Roar
end
```

Contributing
------------

Fork the project. Make your feature addition or bug fix with tests. Send a pull request. Bonus points for topic branches.

Copyright and License
---------------------

MIT License, see [LICENSE](http://github.com/dblock/grape-roar/raw/master/LICENSE) for details.

(c) 2012 [Daniel Doubrovkine](http://github.com/dblock), [Art.sy](http://artsy.github.com)
12 changes: 12 additions & 0 deletions Rakefile
@@ -0,0 +1,12 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"

require 'rspec/core'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |spec|
spec.rspec_opts = ['-fd -c']
spec.pattern = FileList['spec/**/*_spec.rb']
end

task :default => :spec
20 changes: 20 additions & 0 deletions grape-roar.gemspec
@@ -0,0 +1,20 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/grape/roar/version', __FILE__)

Gem::Specification.new do |gem|
gem.authors = ["Daniel Doubrovkine"]
gem.email = ["dblock@dblock.org"]
gem.description = "Use Roar with Grape"
gem.summary = "Enable Resource-Oriented Architectures in Grape API DSL"
gem.homepage = "http://github.com/dblock/grape-roar"

gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
gem.name = "grape-roar"
gem.require_paths = ["lib"]
gem.version = Grape::Roar::VERSION

gem.add_dependency "grape"
gem.add_dependency "roar"
end
3 changes: 3 additions & 0 deletions lib/grape-roar.rb
@@ -0,0 +1,3 @@
require "roar"
require "grape"
require "grape/roar"
2 changes: 2 additions & 0 deletions lib/grape/roar.rb
@@ -0,0 +1,2 @@
require "grape/roar/version"
require "grape/roar/formatter"
13 changes: 13 additions & 0 deletions lib/grape/roar/formatter.rb
@@ -0,0 +1,13 @@
module Grape
module Formatter
module Roar
class << self

def call(object, env)
Grape::Formatter::Json.call object, env
end

end
end
end
end
5 changes: 5 additions & 0 deletions lib/grape/roar/version.rb
@@ -0,0 +1,5 @@
module Grape
module Roar
VERSION = "0.1.0"
end
end
42 changes: 42 additions & 0 deletions spec/nested_representer_spec.rb
@@ -0,0 +1,42 @@
require 'spec_helper'

describe Grape::Roar do
subject do
Class.new(Grape::API)
end

before do
subject.format :json
subject.formatter :json, Grape::Formatter::Roar
end

def app
subject
end

context "order" do

before do

subject.get("/order/:id") {

order = Order.new({
:id => params[:id],
:client_id => 42
})

order.articles << Article.new({ :title => "One", :id => 1 })
order.articles << Article.new({ :title => "Two", :id => 2 })

order.to_json
}

end

it 'returns a hypermedia representation' do
get "/order/666"
last_response.body.should == '{"id":"666","client_id":42,"articles":[{"title":"One","id":1,"links":[{"rel":"self","href":"/article/1"}]},{"title":"Two","id":2,"links":[{"rel":"self","href":"/article/2"}]}],"links":[{"rel":"self","href":"/order/666"},{"rel":"items","href":"/order/666/items"}]}'
end

end
end
34 changes: 34 additions & 0 deletions spec/representer_spec.rb
@@ -0,0 +1,34 @@
require 'spec_helper'

describe Grape::Roar do
subject do
Class.new(Grape::API)
end

before do
subject.format :json
subject.formatter :json, Grape::Formatter::Roar
end

def app
subject
end

context "article" do

before do
subject.get("/article/:id") {
Article.new({
:title => "Lonestar",
:id => params[:id]
}).to_json
}
end

it 'returns a hypermedia representation' do
get "/article/666"
last_response.body.should == '{"title":"Lonestar","id":"666","links":[{"rel":"self","href":"/article/666"}]}'
end

end
end
21 changes: 21 additions & 0 deletions spec/spec_helper.rb
@@ -0,0 +1,21 @@
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))

require 'bundler'
Bundler.setup :default, :test

require 'grape'

require 'roar'
require 'roar/representer/json'
require 'roar/representer/feature/hypermedia'

require 'grape/roar'
require 'rack/test'
require 'rspec'

RSpec.configure do |config|
config.include Rack::Test::Methods
end

Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
14 changes: 14 additions & 0 deletions spec/support/article.rb
@@ -0,0 +1,14 @@
require 'support/article_representer'

class Article
include Roar::Representer::JSON
include ArticleRepresenter

attr_accessor :title, :id

def initialize(attrs = {})
attrs.each_pair do |k, v|
self.send("#{k}=", v)
end
end
end
11 changes: 11 additions & 0 deletions spec/support/article_representer.rb
@@ -0,0 +1,11 @@
module ArticleRepresenter
include Roar::Representer::JSON
include Roar::Representer::Feature::Hypermedia

property :title
property :id

link :self do
"/article/#{id}"
end
end
14 changes: 14 additions & 0 deletions spec/support/order.rb
@@ -0,0 +1,14 @@
require 'support/order_representer'

class Order
include Roar::Representer::JSON
include OrderRepresenter

attr_accessor :id, :client_id, :articles

def initialize(attrs = {})
{ :articles => [] }.merge(attrs).each_pair do |k, v|
self.send("#{k}=", v)
end
end
end
19 changes: 19 additions & 0 deletions spec/support/order_representer.rb
@@ -0,0 +1,19 @@
require 'support/article'

module OrderRepresenter
include Roar::Representer::JSON
include Roar::Representer::Feature::Hypermedia

property :id
property :client_id

collection :articles, :class => Article

link :self do
"/order/#{id}"
end

link :items do
"/order/#{id}/items"
end
end

0 comments on commit 5f81f3c

Please sign in to comment.