raisin 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,7 +18,137 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- Soon
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
+ ```
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
64
+ ```
65
+
66
+ You can see theses names if you run `rake routes` in your console. If you prefer to name your endpoint yourself, you can do it by passing an `:as` option
67
+
68
+ ```ruby
69
+ get '/users', as: :my_method_name
70
+ ```
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
93
+ ```
94
+
95
+ You see that in the `update` method we used a user variable. This is because you can also expose variable for a whole namespace, which does member automatically (the variable name will be the resource name singularize, 'user' in our example)
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
+ ```
114
+
115
+ ### Router
116
+
117
+ raisin router is similar to the `routes.rb` in Rails. APIs that appears at the top have precedence on the ones after. Versionning is done by encapsulating APIs inside `version` block. `:all` can be used is a part of your api is accessible for all versions.
118
+
119
+ ```ruby
120
+ # /app/api/my_api.rb
121
+ class MyApi < Raisin::Router
122
+ version :v2, using: :header, vendor: 'mycompany' do
123
+ mount CommentsApi
124
+ end
125
+
126
+ version [:v2, :v1] do
127
+ mount PostsApi
128
+ mount UsersApi
129
+ end
130
+
131
+ version :all do
132
+ mount LoginApi
133
+ end
134
+ end
135
+
136
+ # /config/routes.rb
137
+
138
+ mount_api MyApi
139
+ ```
140
+
141
+ Versionning can be done via the HTTP Accept header (application/vnd.mycompany-v1+json for example) or via the URL
142
+ (/v1/users/). When using the header versionning, the vendor must be set. These options can be set globally when configuring raisin.
143
+
144
+ ## Configuration
145
+
146
+ ```ruby
147
+ Raisin.configure do |c|
148
+ c.version.using = :header
149
+ c.version.vendor = 'mycompany'
150
+ end
151
+ ```
22
152
 
23
153
  ## Contributing
24
154
 
data/lib/raisin/api.rb CHANGED
@@ -5,18 +5,14 @@ module Raisin
5
5
  @args = args
6
6
  end
7
7
  end
8
-
9
- def build(action, app=nil, &block)
10
- super(app, &block)
11
- end
12
8
  end
13
9
 
14
10
  class API
15
- class_attribute :middleware_stack
16
- self.middleware_stack = Raisin::MiddlewareStack.new
11
+ cattr_accessor :middleware_stack
12
+ @@middleware_stack = Raisin::MiddlewareStack.new
17
13
 
18
14
  def self.action(name, klass = ActionDispatch::Request)
19
- middleware_stack.build(name) do |env|
15
+ middleware_stack.build do |env|
20
16
  self.const_get(name.camelize).new.dispatch(:call, klass.new(env))
21
17
  end
22
18
  end
@@ -51,10 +47,10 @@ module Raisin
51
47
  end
52
48
 
53
49
  def self.inherited(subclass)
50
+ super
54
51
  subclass.reset
55
52
  subclass.middleware_stack = self.middleware_stack.dup
56
53
  subclass.action_klass = self.action_klass.dup
57
- super
58
54
  end
59
55
 
60
56
  def self.api_name
@@ -1,3 +1,3 @@
1
1
  module Raisin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raisin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-13 00:00:00.000000000 Z
12
+ date: 2012-12-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: An opiniated micro-framework to easily build elegant API on top of Rails
15
15
  email: