restaurant 0.1.1 → 0.1.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: 9cc774878cfd70d875198554dc08a0c02699de0c
4
- data.tar.gz: a9f90a959400a81935d5441a21ddc3770264368a
3
+ metadata.gz: b3f1d76c4e2e076ae74aab8564275da04ef24a55
4
+ data.tar.gz: d86e4d33694c9faba170aeec9deb699cb78be05c
5
5
  SHA512:
6
- metadata.gz: 5b11d73e5068aad446ab0ed0b23191236c0729ea848bdf344ff35c9153d1bb463e6e426a7abc9184d94e9e5cd22600fca8adec9300c7a1de91becf809aa0a765
7
- data.tar.gz: ce710ac1bff61b2d2cb876aaa8ee37d69b0c2de32ee7ba41737d3cc276d6ea8101df18bb14a4ce7e3bbe600bbcf8010e66041a2eeb1d3f0b8f61e58855317603
6
+ metadata.gz: 996b518bb2182fed86fd59e97ec8ae4f01a1d5c8570cc03c2132ee005c27d5a615226ae7ca8d99bb96046bc96151a4c0d4bcd75753b82efac759fa8daaf93fc0
7
+ data.tar.gz: ac833d067a1e7be9a37c95a1e2632c631394c29b9a2ebbc68214b63713bff71c60c02be4c9e65f883a6da247d2d254911b2377faeaf780a4211f267ea3ab7824
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # Restaurant
2
- Restaurant serves your data via auto-defined RESTful API on your rails application.
2
+ Restaurant serves your data via auto-defined RESTful API on your rails application.
3
+ No longer models, controllers, views, routes, and schemas are needed.
3
4
 
4
5
  ## Usage
6
+ Here is an example that creates a new rails app with Restaurant to provide RESTful API.
7
+
5
8
  ```
6
9
  $ brew install mongodb
7
10
  $ mongod --fork
@@ -15,33 +18,110 @@ $ bundle install
15
18
  $ rails g mongoid:config
16
19
  $ rails c
17
20
 
18
- [1] pry(main)> app.accept = "application/json"
21
+ irb(main):001:0> app.accept = "application/json"
19
22
  => "application/json"
20
- [2] pry(main)> app.post "/recipes", recipe: { title: "created" }
23
+ irb(main):002:0> app.post "/recipes", recipe: { title: "created" }
21
24
  => 201
22
- [3] pry(main)> JSON.parse(app.response.body)
25
+ irb(main):003:0 JSON.parse(app.response.body)
23
26
  => {"title"=>"created", "_id"=>"51963fe9f02da4c1f8000001"}
24
- [4] pry(main)> app.get "/recipes/51963fe9f02da4c1f8000001"
27
+ irb(main):004:0> app.get "/recipes/51963fe9f02da4c1f8000001"
25
28
  => 200
26
- [5] pry(main)> JSON.parse(app.response.body)
29
+ irb(main):005:0> JSON.parse(app.response.body)
27
30
  => {"title"=>"created", "_id"=>"51963fe9f02da4c1f8000001"}
28
- [6] pry(main)> app.put "/recipes/51963fe9f02da4c1f8000001", recipe: { title: "updated" }
31
+ irb(main):006:0> app.put "/recipes/51963fe9f02da4c1f8000001", recipe: { title: "updated" }
29
32
  => 204
30
- [7] pry(main)> app.get "/recipes/51963fe9f02da4c1f8000001"
33
+ irb(main):007:0> app.get "/recipes/51963fe9f02da4c1f8000001"
31
34
  => 200
32
- [8] pry(main)> JSON.parse(app.response.body)
35
+ irb(main):008:0> JSON.parse(app.response.body)
33
36
  => {"title"=>"updated", "_id"=>"51963fe9f02da4c1f8000001"}
34
- [9] pry(main)> app.get "/recipes"
37
+ irb(main):009:0> app.get "/recipes"
35
38
  => 200
36
- [10] pry(main)> JSON.parse(app.response.body)
39
+ irb(main):010:0> JSON.parse(app.response.body)
37
40
  => [{"title"=>"updated", "_id"=>"51963fe9f02da4c1f8000001"}]
38
- [11] pry(main)> app.delete "/recipes/51963fe9f02da4c1f8000001"
41
+ irb(main):011:0> app.delete "/recipes/51963fe9f02da4c1f8000001"
39
42
  => 204
40
- [12] pry(main)> app.get "/recipes"
43
+ irb(main):012:0> app.get "/recipes"
41
44
  => 200
42
- [13] pry(main)> JSON.parse(app.response.body)
45
+ irb(main):013:0> JSON.parse(app.response.body)
43
46
  => []
44
47
  ```
45
48
 
49
+ ## Customize
50
+ While Restaurant automagically defines what RESTful API needs, you can do them on your own.
51
+
52
+ ### routes
53
+ ```ruby
54
+ # config/routes.rb
55
+ # 1. V1::ResourcesController < ApplicationController are defined if not defined
56
+ # 2. The following routes are defined
57
+ # GET /v1/:resources -> V1::ReosurcesController#index
58
+ # GET /v1/:resources/:id -> V1::ResourcesController#show
59
+ # POST /v1/:resources -> V1::ResourcesController#create
60
+ # PUT /v1/:resources/:id -> V1::ResourcesController#update
61
+ # DELETE /v1/:resources/:id -> V1::ResourcesController#destroy
62
+ namespace :v1 do
63
+ Restaurant::Router.route(self)
64
+ end
65
+
66
+ # Or customize what you want (e.g. only provides Read API)
67
+ namespace :v2 do
68
+ scope ":resource" do
69
+ controller :resources do
70
+ get "" => :index
71
+ get ":id" => :show
72
+ end
73
+ end
74
+ end
75
+ ```
76
+
77
+ ### controller
78
+ ```ruby
79
+ # Restaurant::Actions provides index, show, create, update, and destroy actions by default.
80
+ # Of course you can override them as you like.
81
+ module V1
82
+ class ResourcesController < ApplicationController
83
+ include Restaurant::Actions
84
+ respond_to :xml # you can respond to xml requests
85
+
86
+ def index
87
+ respond_with { foo: "bar" }
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
93
+ ### authentication & authorization
94
+ Restaurant does not provide any auth layer, but it's easy to add it to your application.
95
+ Here is a short example to authenticate users with [doorkeeper](https://github.com/applicake/doorkeeper).
96
+
97
+ ```
98
+ $ echo 'gem "doorkeeper"' >> Gemfile
99
+ $ bundle install
100
+
101
+ $ rails g doorkeeper:install
102
+ $ rails g doorkeeper:migration
103
+ $ bundle exec rake db:migrate
104
+
105
+ $ vi app/controllers/application_controller.rb
106
+ class ApplicationController < ActionController::Base
107
+ doorkeeper_for :all
108
+ end
109
+
110
+ $ rails c
111
+
112
+ irb(main):001:0> app.accept = "application/json"
113
+ => "application/json"
114
+ irb(main):002:0> app.get "/v2/recipes"
115
+ => 401
116
+ irb(main):003:0> application = Doorkeeper::Application.create(name: "example", redirect_uri: "http://example.com")
117
+ => #<Doorkeeper::Application ...>
118
+ irb(main):004:0> create = application.access_tokens.create
119
+ => #<Doorkeeper::AccessToken ...>
120
+ irb(main):005:0> app.get "/v2/recipes", access_token: token.token
121
+ => 200
122
+ irb(main):006:0> JSON.parse(app.response.body)
123
+ => [...]
124
+ ```
125
+
46
126
  ## More
47
127
  See [the example application](https://github.com/r7kamura/restaurant/tree/master/spec/dummy).
@@ -1,20 +1,24 @@
1
1
  module Restaurant
2
2
  module Actions
3
+ def self.included(base)
4
+ base.before_filter :require_valid_id, :require_resource, :only => [:show, :update, :destroy]
5
+ end
6
+
3
7
  def index
4
- respond_with collection.find
8
+ respond_with collection.find(filter_params).sort(sort_params).skip(skip_params).limit(limit_params)
5
9
  end
6
10
 
7
11
  def show
8
- respond_with collection.find(:_id => resource_id).first
12
+ respond_with @resource
9
13
  end
10
14
 
11
15
  def create
12
- collection.insert(resource_param.merge(:_id => resource_id))
16
+ collection.insert(resource_params.merge(:_id => resource_id))
13
17
  respond_with collection.find(:_id => resource_id).first, :location => { :action => :show, :id => resource_id }
14
18
  end
15
19
 
16
20
  def update
17
- respond_with collection.find(:_id => resource_id).update(:$set => resource_param)
21
+ respond_with collection.find(:_id => resource_id).update(:$set => resource_params)
18
22
  end
19
23
 
20
24
  def destroy
@@ -23,8 +27,16 @@ module Restaurant
23
27
 
24
28
  private
25
29
 
30
+ def require_valid_id
31
+ head 404 unless Moped::BSON::ObjectId.legal?(params[:id])
32
+ end
33
+
34
+ def require_resource
35
+ @resource = collection.find(:_id => resource_id).first || head(404)
36
+ end
37
+
26
38
  def collection
27
- Mongoid.default_session.with(:safe => true)[resources_name]
39
+ Mongoid.default_session[resources_name]
28
40
  end
29
41
 
30
42
  def resource_name
@@ -35,8 +47,8 @@ module Restaurant
35
47
  params[:resource]
36
48
  end
37
49
 
38
- def resource_param
39
- params[resource_name]
50
+ def resource_params
51
+ params[resource_name] || {}
40
52
  end
41
53
 
42
54
  def resource_id
@@ -48,5 +60,37 @@ module Restaurant
48
60
  end
49
61
  end
50
62
  end
63
+
64
+ def filter_params
65
+ params[:filter] || {}
66
+ end
67
+
68
+ def sort_params
69
+ if params[:sort]
70
+ Hash[
71
+ params[:sort].map do |key, value|
72
+ [key, value.to_i]
73
+ end
74
+ ]
75
+ else
76
+ {}
77
+ end
78
+ end
79
+
80
+ def skip_params
81
+ (page - 1) * per_page
82
+ end
83
+
84
+ def limit_params
85
+ per_page
86
+ end
87
+
88
+ def page
89
+ [params[:page].to_i, 1].max
90
+ end
91
+
92
+ def per_page
93
+ 10
94
+ end
51
95
  end
52
96
  end
@@ -1,3 +1,3 @@
1
1
  module Restaurant
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restaurant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-17 00:00:00.000000000 Z
11
+ date: 2013-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: doorkeeper
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rails
29
43
  requirement: !ruby/object:Gem::Requirement