restaurant 0.1.1 → 0.1.2

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 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