raisin 0.1.2 → 0.2.0
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 +7 -0
- data/.gitignore +1 -0
- data/Gemfile +7 -0
- data/{LICENSE.txt → MIT-LICENSE} +1 -1
- data/README.md +17 -128
- data/Rakefile +12 -1
- data/lib/raisin.rb +12 -6
- data/lib/raisin/mapper.rb +17 -0
- data/lib/raisin/middleware.rb +12 -14
- data/lib/raisin/railtie.rb +9 -4
- data/lib/raisin/version.rb +1 -1
- data/lib/raisin/version_constraint.rb +11 -0
- data/raisin.gemspec +18 -12
- data/test/helper.rb +11 -0
- data/test/test_middleware.rb +29 -0
- metadata +50 -22
- data/lib/raisin/base.rb +0 -69
- data/lib/raisin/configuration.rb +0 -16
- data/lib/raisin/rails/request.rb +0 -20
- data/lib/raisin/rails/routes.rb +0 -37
- data/lib/raisin/routing.rb +0 -16
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e79d5231cce8b38d975dd0b1bee00793e427d01d
|
4
|
+
data.tar.gz: 822e2c2868222cdef4265df60e3852c3c98611c0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d94015c5476fc070466a0299cedd2ce9d58d71a392fcf5e412a1ee12c880a638c84afff29f4782c113dd60347171dd7c0f076dde9c74c05b0bdff0bb03a0f461
|
7
|
+
data.tar.gz: 15d704101d562793fcb3ae885438eac47d49c5f44c081ae27fd3cc99949b990c5ab3ddf2c6ee1cd5be5c19116af9ceb02d1949046a49f2d689c3d936067735dd
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,163 +1,52 @@
|
|
1
1
|
# Raisin
|
2
2
|
|
3
|
-
|
3
|
+
API versioning via the Accept header.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
Install as a gem :
|
8
8
|
|
9
|
-
gem 'raisin'
|
10
|
-
|
11
|
-
And then execute:
|
12
|
-
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install raisin
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
Raisin is composed of two main elements : a router and a lists of API. An API is a file containing your endpoints,
|
22
|
-
with their paths, implementation and documentation. The router is where you modelize your API, saying which
|
23
|
-
API goes to which version.
|
24
|
-
|
25
|
-
Under the hood, raisin will generate classes (one for each enpoint), enabling us to use unit test for them, but keeping it transparent for Rails router.
|
26
|
-
|
27
|
-
Here's a basic example of an API
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
class UsersAPI < Raisin::API
|
31
|
-
get '/users' do
|
32
|
-
expose(:user) { User.all }
|
33
|
-
end
|
34
|
-
|
35
|
-
post do
|
36
|
-
expose(:user) { User.new(params[:user]) }
|
37
|
-
|
38
|
-
response do
|
39
|
-
user.save
|
40
|
-
respond_with(user)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
9
|
```
|
45
|
-
|
46
|
-
### Endpoints
|
47
|
-
|
48
|
-
Each endoint is defined by the http verb used to access it, its path and its implementation. When the path is omitted, raisin will default it to '/'. And since we are in the UsersAPI, raisin will set a prefix to 'users'. So the `post do` is equivalent to `post '/users' do`.
|
49
|
-
Same for the get method, since its path is the same as the prefix, it can be omitted.
|
50
|
-
|
51
|
-
The `expose` method allows you to create variables elegantly and to access it in your endpoints body or your views (in you gems like jbuilder or rabl-rails). These exposed variables are evaluated in the response block so you have access to everything (like the params object).
|
52
|
-
|
53
|
-
The response block is where your endpoint logic goes. It can be optionnal, as you can see in the get method. If no response is specified, raisin will behave like a a standart rails controller method (thus trying to render a file with tht same name as the endpoint or fallback to API rendering)
|
54
|
-
|
55
|
-
We talk about the name of the endpoint but how is it determine? raisin is smart enough to recognize basic CRUD operations and RESTful endpoint
|
56
|
-
|
57
|
-
```ruby
|
58
|
-
class UsersAPI < Raisin::API
|
59
|
-
get '/users' {} # index
|
60
|
-
post '/users' {} # create
|
61
|
-
|
62
|
-
put '/users/:id/foo' # foo
|
63
|
-
end
|
10
|
+
gem install raisin
|
64
11
|
```
|
65
12
|
|
66
|
-
|
13
|
+
or add directly to your `Gemfile`
|
67
14
|
|
68
|
-
```ruby
|
69
|
-
get '/users', as: :my_method_name
|
70
15
|
```
|
71
|
-
|
72
|
-
### Namespaces
|
73
|
-
|
74
|
-
You often have endpoint that have a portion of their path in commons, a namespace in raisin. The most used is RESTful applications is the "member" namespace, that look like `/resource_name/:id`.
|
75
|
-
|
76
|
-
raisin provides both generic namespace and member out of the box
|
77
|
-
|
78
|
-
```ruby
|
79
|
-
class UsersAPI < Raisin::API
|
80
|
-
namespace 'foo' do
|
81
|
-
get '/bar' {} # GET /foo/bar
|
82
|
-
end
|
83
|
-
|
84
|
-
member do
|
85
|
-
put do # PUT /users/:id
|
86
|
-
response do
|
87
|
-
user.update_attributes(params[:user])
|
88
|
-
respond_with(user)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
16
|
+
gem 'raisin'
|
93
17
|
```
|
94
18
|
|
95
|
-
|
96
|
-
|
97
|
-
Namespaces can be nested.
|
98
|
-
|
99
|
-
### Miscellanous
|
100
|
-
|
101
|
-
You can add `single_resource` in your API for single resources.
|
102
|
-
|
103
|
-
Resources can be nested just as regular Rails. For example
|
104
|
-
|
105
|
-
```ruby
|
106
|
-
class CommentsAPI < Raisin::API
|
107
|
-
nested_into_resource :posts
|
108
|
-
|
109
|
-
get '/comments/:id' do # GET /posts/:post_id/comments/:id
|
110
|
-
expose(:comment) { post.comments.find(params[:id]) }
|
111
|
-
end
|
112
|
-
end
|
113
|
-
```
|
19
|
+
## Usage
|
114
20
|
|
115
|
-
|
21
|
+
`raisin` allows you to encapsulate your routes within API versions, using a custom `Accept` header to routes them to your controller accordingly.
|
116
22
|
|
117
|
-
|
23
|
+
It uses the fact that Rails router is resolved top to bottom.
|
118
24
|
|
119
25
|
```ruby
|
120
|
-
# /
|
121
|
-
class MyApi < Raisin::Router
|
122
|
-
version :v2, using: :header, vendor: 'mycompany' do
|
123
|
-
mount CommentsApi
|
124
|
-
end
|
26
|
+
# config/routes.rb
|
125
27
|
|
126
|
-
|
127
|
-
|
128
|
-
|
28
|
+
Rails.application.routes.draw do
|
29
|
+
api :v2 do
|
30
|
+
resources :users, only: :show
|
129
31
|
end
|
130
32
|
|
131
|
-
|
132
|
-
|
33
|
+
api :v1, default: true do
|
34
|
+
resources :users
|
35
|
+
get '/users/sign_in', to: 'sessions#new'
|
133
36
|
end
|
134
37
|
end
|
135
|
-
|
136
|
-
# /config/routes.rb
|
137
|
-
|
138
|
-
mount_api MyApi
|
139
38
|
```
|
140
39
|
|
141
|
-
|
142
|
-
(/v1/users/). When using the header versionning, the vendor must be set. These options can be set globally when configuring raisin.
|
40
|
+
Clients using the version `v2` will have access to all the methods from the `v1` version plus their `/users/show` routes will be overriden the the new one define in the first `api` block.
|
143
41
|
|
144
42
|
## Configuration
|
145
43
|
|
146
44
|
```ruby
|
147
45
|
Raisin.configure do |c|
|
148
|
-
c.
|
149
|
-
c.version.vendor = 'mycompany'
|
46
|
+
c.vendor = 'mycompany' # replace with your vendor
|
150
47
|
end
|
151
48
|
```
|
152
49
|
|
153
|
-
If you are using versionning via header, you also need to add a middleware to your application stack
|
154
|
-
|
155
|
-
```ruby
|
156
|
-
#config/application.rb
|
157
|
-
|
158
|
-
config.middleware.use Raisin::Middleware
|
159
|
-
```
|
160
|
-
|
161
50
|
## Contributing
|
162
51
|
|
163
52
|
1. Fork it
|
data/Rakefile
CHANGED
data/lib/raisin.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
require 'raisin/version'
|
2
|
-
require 'raisin/
|
3
|
-
|
4
|
-
require 'raisin/base'
|
2
|
+
require 'raisin/mapper'
|
5
3
|
require 'raisin/middleware'
|
6
4
|
|
5
|
+
require 'raisin/railtie' if defined?(Rails)
|
6
|
+
|
7
7
|
module Raisin
|
8
8
|
def self.configure
|
9
|
-
yield
|
9
|
+
yield self
|
10
10
|
end
|
11
|
-
end
|
12
11
|
|
13
|
-
|
12
|
+
def self.vendor
|
13
|
+
@vendor || raise('`vendor` is not configured')
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.vendor=(value)
|
17
|
+
@vendor = value
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'raisin/version_constraint'
|
2
|
+
|
3
|
+
module Raisin
|
4
|
+
module Mapper
|
5
|
+
def api(version, default: false)
|
6
|
+
return unless block_given?
|
7
|
+
|
8
|
+
version = version.to_s
|
9
|
+
raise 'Version is missing in constraint' if version.blank?
|
10
|
+
constraint = Raisin::VersionConstraint.new(version) unless default
|
11
|
+
|
12
|
+
scope(module: version, constraints: constraint) do
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/raisin/middleware.rb
CHANGED
@@ -4,29 +4,27 @@ module Raisin
|
|
4
4
|
# It stores version and format accepted by the client in the env.
|
5
5
|
#
|
6
6
|
class Middleware
|
7
|
-
ACCEPT_REGEXP =
|
7
|
+
ACCEPT_REGEXP = /\Aapplication\/vnd\.(?<vendor>[a-z]+).(?<version>v[0-9]+)\+(?<format>[a-z]+)\Z/
|
8
8
|
|
9
9
|
def initialize(app)
|
10
|
-
@app
|
11
|
-
@vendor =
|
10
|
+
@app = app
|
11
|
+
@vendor = Raisin.vendor
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(env)
|
15
|
-
|
16
|
-
|
17
|
-
@app.call(@env)
|
15
|
+
extract_version_from_accept_header(ActionDispatch::Request.new(env))
|
16
|
+
@app.call(env)
|
18
17
|
end
|
19
18
|
|
20
19
|
private
|
21
20
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
false
|
21
|
+
def extract_version_from_accept_header(req)
|
22
|
+
header = req.get_header('HTTP_ACCEPT'.freeze).to_s.strip
|
23
|
+
|
24
|
+
if (matches = ACCEPT_REGEXP.match(header)) && @vendor == matches[:vendor]
|
25
|
+
req.set_header('raisin.version'.freeze, matches[:version])
|
26
|
+
req.format = matches[:format]
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
32
|
-
end
|
30
|
+
end
|
data/lib/raisin/railtie.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
require 'raisin/rails/routes'
|
2
|
-
require 'raisin/rails/request'
|
3
|
-
|
4
1
|
module Raisin
|
5
2
|
class Railtie < Rails::Railtie
|
3
|
+
|
4
|
+
initializer 'raisin.middleware' do |app|
|
5
|
+
app.middleware.use Raisin::Middleware
|
6
|
+
end
|
7
|
+
|
8
|
+
initializer 'raisin.patch_rails' do
|
9
|
+
ActionDispatch::Routing::Mapper.include(Raisin::Mapper)
|
10
|
+
end
|
6
11
|
end
|
7
|
-
end
|
12
|
+
end
|
data/lib/raisin/version.rb
CHANGED
data/raisin.gemspec
CHANGED
@@ -3,17 +3,23 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'raisin/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "raisin"
|
8
|
+
s.version = Raisin::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["ccocchi"]
|
11
|
+
s.email = ["cocchi.c@gmail.com"]
|
12
|
+
s.description = %q{API versioning via the Accept header}
|
13
|
+
s.summary = %q{Build API with Accept header versioning on top of Rails}
|
14
|
+
s.homepage = "https://github.com/ccocchi/raisin"
|
15
|
+
s.license = 'MIT'
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
s.required_ruby_version = '>= 2.2.0'
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency 'actionpack', '~> 5.0'
|
24
|
+
s.add_dependency 'activesupport', '~> 5.0'
|
19
25
|
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestMiddleware < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@middleware = Raisin::Middleware.new(->(env) { :ok })
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_not_vendored_header
|
9
|
+
assert_equal :ok, @middleware.call({})
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_wrong_vendor_header
|
13
|
+
env = {}
|
14
|
+
|
15
|
+
assert_equal :ok, @middleware.call(env)
|
16
|
+
assert_empty env
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_vendored_header
|
20
|
+
env = {
|
21
|
+
'action_dispatch.request.parameters' => {},
|
22
|
+
'HTTP_ACCEPT' => 'application/vnd.acme.v1+json'
|
23
|
+
}
|
24
|
+
|
25
|
+
assert_equal :ok, @middleware.call(env)
|
26
|
+
assert_equal 'v1', env['raisin.version']
|
27
|
+
refute_empty env['action_dispatch.request.formats']
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,60 +1,88 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: raisin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- ccocchi
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
11
|
+
date: 2017-10-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
description: API versioning via the Accept header
|
15
42
|
email:
|
16
43
|
- cocchi.c@gmail.com
|
17
44
|
executables: []
|
18
45
|
extensions: []
|
19
46
|
extra_rdoc_files: []
|
20
47
|
files:
|
21
|
-
- .gitignore
|
48
|
+
- ".gitignore"
|
22
49
|
- Gemfile
|
23
|
-
- LICENSE
|
50
|
+
- MIT-LICENSE
|
24
51
|
- README.md
|
25
52
|
- Rakefile
|
26
53
|
- lib/raisin.rb
|
27
|
-
- lib/raisin/
|
28
|
-
- lib/raisin/configuration.rb
|
54
|
+
- lib/raisin/mapper.rb
|
29
55
|
- lib/raisin/middleware.rb
|
30
|
-
- lib/raisin/rails/request.rb
|
31
|
-
- lib/raisin/rails/routes.rb
|
32
56
|
- lib/raisin/railtie.rb
|
33
|
-
- lib/raisin/routing.rb
|
34
57
|
- lib/raisin/version.rb
|
58
|
+
- lib/raisin/version_constraint.rb
|
35
59
|
- raisin.gemspec
|
60
|
+
- test/helper.rb
|
61
|
+
- test/test_middleware.rb
|
36
62
|
homepage: https://github.com/ccocchi/raisin
|
37
|
-
licenses:
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
metadata: {}
|
38
66
|
post_install_message:
|
39
67
|
rdoc_options: []
|
40
68
|
require_paths:
|
41
69
|
- lib
|
42
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
71
|
requirements:
|
45
|
-
- -
|
72
|
+
- - ">="
|
46
73
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
74
|
+
version: 2.2.0
|
48
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
76
|
requirements:
|
51
|
-
- -
|
77
|
+
- - ">="
|
52
78
|
- !ruby/object:Gem::Version
|
53
79
|
version: '0'
|
54
80
|
requirements: []
|
55
81
|
rubyforge_project:
|
56
|
-
rubygems_version:
|
82
|
+
rubygems_version: 2.6.13
|
57
83
|
signing_key:
|
58
|
-
specification_version:
|
59
|
-
summary:
|
60
|
-
test_files:
|
84
|
+
specification_version: 4
|
85
|
+
summary: Build API with Accept header versioning on top of Rails
|
86
|
+
test_files:
|
87
|
+
- test/helper.rb
|
88
|
+
- test/test_middleware.rb
|
data/lib/raisin/base.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
module Raisin
|
2
|
-
|
3
|
-
#
|
4
|
-
# Abstract class for all actions.
|
5
|
-
#
|
6
|
-
class Base < ActionController::Metal
|
7
|
-
abstract!
|
8
|
-
|
9
|
-
module Compatibility
|
10
|
-
def cache_store; end
|
11
|
-
def cache_store=(*); end
|
12
|
-
def assets_dir=(*); end
|
13
|
-
def javascripts_dir=(*); end
|
14
|
-
def stylesheets_dir=(*); end
|
15
|
-
def page_cache_directory=(*); end
|
16
|
-
def asset_path=(*); end
|
17
|
-
def asset_host=(*); end
|
18
|
-
def relative_url_root=(*); end
|
19
|
-
def perform_caching=(*); end
|
20
|
-
def helpers_path=(*); end
|
21
|
-
def allow_forgery_protection=(*); end
|
22
|
-
end
|
23
|
-
|
24
|
-
extend Compatibility
|
25
|
-
|
26
|
-
MODULES = [
|
27
|
-
AbstractController::Helpers,
|
28
|
-
ActionController::UrlFor,
|
29
|
-
ActionController::Rendering,
|
30
|
-
ActionController::Renderers::All,
|
31
|
-
|
32
|
-
ActionController::ConditionalGet,
|
33
|
-
|
34
|
-
ActionController::RackDelegation,
|
35
|
-
ActionController::MimeResponds,
|
36
|
-
ActionController::ImplicitRender,
|
37
|
-
ActionController::DataStreaming,
|
38
|
-
|
39
|
-
AbstractController::Callbacks,
|
40
|
-
ActionController::Rescue,
|
41
|
-
|
42
|
-
ActionController::Instrumentation,
|
43
|
-
]
|
44
|
-
|
45
|
-
if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR > 0
|
46
|
-
include AbstractController::Rendering
|
47
|
-
include ActionView::Rendering
|
48
|
-
end
|
49
|
-
|
50
|
-
MODULES.each { |mod|
|
51
|
-
include mod
|
52
|
-
}
|
53
|
-
|
54
|
-
if Rails::VERSION::MAJOR >= 4
|
55
|
-
include ActionController::StrongParameters
|
56
|
-
end
|
57
|
-
|
58
|
-
def _prefixes
|
59
|
-
@_prefixes ||= begin
|
60
|
-
parent_prefixes = self.class.parent_prefixes.dup
|
61
|
-
parent_prefixes.unshift(controller_path)
|
62
|
-
parent_prefixes.unshift("#{env['raisin.version']}/#{controller_name}") if env.key?('raisin.version')
|
63
|
-
parent_prefixes
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
ActiveSupport.run_load_hooks(:action_controller, self)
|
68
|
-
end
|
69
|
-
end
|
data/lib/raisin/configuration.rb
DELETED
data/lib/raisin/rails/request.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module Raisin
|
2
|
-
module ApiFormat
|
3
|
-
def formats
|
4
|
-
@env["action_dispatch.request.formats"] ||=
|
5
|
-
if @env.key?('raisin.format')
|
6
|
-
Array(Mime::Type.lookup(@env['raisin.format']))
|
7
|
-
elsif parameters[:format]
|
8
|
-
Array(Mime[parameters[:format]])
|
9
|
-
elsif use_accept_header && valid_accept_header
|
10
|
-
accepts
|
11
|
-
elsif xhr?
|
12
|
-
[Mime::JS]
|
13
|
-
else
|
14
|
-
[Mime::HTML]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
ActionDispatch::Request.send(:include, Raisin::ApiFormat)
|
data/lib/raisin/rails/routes.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'raisin/routing'
|
2
|
-
|
3
|
-
module ActionDispatch::Routing
|
4
|
-
class Mapper
|
5
|
-
|
6
|
-
def api(options, &block)
|
7
|
-
return unless block_given?
|
8
|
-
|
9
|
-
version = options[:version].to_s
|
10
|
-
is_default = options.fetch(:default, false)
|
11
|
-
|
12
|
-
raise 'Version is missing in constraint' if version.blank?
|
13
|
-
|
14
|
-
@api_resources = true
|
15
|
-
|
16
|
-
send(:constraints, Raisin::Routing::VersionConstraint.new(version, is_default)) do
|
17
|
-
send(:scope, module: version) do
|
18
|
-
yield
|
19
|
-
end
|
20
|
-
end
|
21
|
-
ensure
|
22
|
-
@api_resources = nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def resources(*resources, &block)
|
26
|
-
if @api_resources
|
27
|
-
options = resources.extract_options!
|
28
|
-
options[:except] ||= []
|
29
|
-
options[:except].concat([:new, :edit])
|
30
|
-
super(*resources, options)
|
31
|
-
else
|
32
|
-
super
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
data/lib/raisin/routing.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Raisin
|
2
|
-
module Routing
|
3
|
-
ALL_VERSIONS = 'all'
|
4
|
-
|
5
|
-
class VersionConstraint
|
6
|
-
def initialize(version, is_default)
|
7
|
-
@version = version
|
8
|
-
@bypass = is_default || version == ALL_VERSIONS
|
9
|
-
end
|
10
|
-
|
11
|
-
def matches?(req)
|
12
|
-
@bypass || @version == req.env['raisin.version']
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|