grape 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- data/.rspec +1 -2
- data/Gemfile +3 -0
- data/Gemfile.lock +1 -0
- data/LICENSE +1 -1
- data/README.markdown +75 -0
- data/Rakefile +35 -9
- data/VERSION +1 -1
- data/grape.gemspec +4 -4
- data/lib/grape/api.rb +85 -45
- data/lib/grape/endpoint.rb +26 -4
- data/lib/grape/middleware/formatter.rb +1 -1
- data/spec/grape/api_spec.rb +61 -1
- data/spec/grape/endpoint_spec.rb +29 -0
- metadata +6 -6
- data/README.rdoc +0 -52
data/.rspec
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/LICENSE
CHANGED
data/README.markdown
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Grape
|
2
|
+
|
3
|
+
Grape is a REST-like API micro-framework for Ruby. It is built to complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily provide APIs. It has built-in support for common conventions such as multiple formats, subdomain/prefix restriction, and versioning.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Grape is available as a gem, to install it just install the gem:
|
8
|
+
|
9
|
+
gem install grape
|
10
|
+
|
11
|
+
## Basic Usage
|
12
|
+
|
13
|
+
Grape APIs are Rack applications that are created by subclassing `Grape::API`. Below is a simple example showing some of the more common features of Grape in the context of recreating parts of the Twitter API.
|
14
|
+
|
15
|
+
class Twitter::API < Grape::Base
|
16
|
+
version '1'
|
17
|
+
|
18
|
+
helpers do
|
19
|
+
def current_user
|
20
|
+
@current_user ||= User.authorize!(env)
|
21
|
+
end
|
22
|
+
|
23
|
+
def authenticate!
|
24
|
+
error!('401 Unauthorized', 401) unless current_user
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
resource :statuses do
|
29
|
+
get :public_timeline do
|
30
|
+
Tweet.limit(20)
|
31
|
+
end
|
32
|
+
|
33
|
+
get :home_timeline do
|
34
|
+
authenticate!
|
35
|
+
current_user.home_timeline
|
36
|
+
end
|
37
|
+
|
38
|
+
get '/show/:id' do
|
39
|
+
Tweet.find(params[:id])
|
40
|
+
end
|
41
|
+
|
42
|
+
post :update do
|
43
|
+
authenticate!
|
44
|
+
Tweet.create(
|
45
|
+
:user => current_user,
|
46
|
+
:text => params[:status]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
This would create a Rack application that could be used like so (in a Rackup file):
|
53
|
+
|
54
|
+
use Twitter::API
|
55
|
+
|
56
|
+
And would respond to the following routes:
|
57
|
+
|
58
|
+
GET /1/statuses/public_timeline(.json)
|
59
|
+
GET /1/statuses/home_timeline(.json)
|
60
|
+
GET /1/statuses/show/:id(.json)
|
61
|
+
POST /1/statuses/update(.json)
|
62
|
+
|
63
|
+
Serialization takes place automatically. For more detailed usage information, please visit the [Grape Wiki](http://github.com/intridea/grape/wiki).
|
64
|
+
|
65
|
+
## Note on Patches/Pull Requests
|
66
|
+
|
67
|
+
* Fork the project.
|
68
|
+
* Make your feature addition or bug fix.
|
69
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
70
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
71
|
+
* Send me a pull request. Bonus points for topic branches.
|
72
|
+
|
73
|
+
## Copyright
|
74
|
+
|
75
|
+
Copyright (c) 2010 Michael Bleigh and Intridea, Inc. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -3,6 +3,10 @@ require 'bundler'
|
|
3
3
|
|
4
4
|
Bundler.setup :default, :test, :development
|
5
5
|
|
6
|
+
def version
|
7
|
+
@version ||= open('VERSION').read.trim
|
8
|
+
end
|
9
|
+
|
6
10
|
begin
|
7
11
|
require 'jeweler'
|
8
12
|
Jeweler::Tasks.new do |gem|
|
@@ -33,12 +37,34 @@ end
|
|
33
37
|
task :spec => :check_dependencies
|
34
38
|
task :default => :spec
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
40
|
+
begin
|
41
|
+
require 'yard'
|
42
|
+
YARD_OPTS = ['-m', 'markdown', '-M', 'maruku']
|
43
|
+
DOC_FILES = ['lib/**/*.rb', 'README.markdown']
|
44
|
+
|
45
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
46
|
+
t.files = DOC_FILES
|
47
|
+
t.options = YARD_OPTS
|
48
|
+
end
|
49
|
+
|
50
|
+
namespace :doc do
|
51
|
+
YARD::Rake::YardocTask.new(:pages) do |t|
|
52
|
+
t.files = DOC_FILES
|
53
|
+
t.options = YARD_OPTS + ['-o', '../grape.doc']
|
54
|
+
end
|
55
|
+
|
56
|
+
namespace :pages do
|
57
|
+
desc 'Generate and publish YARD docs to GitHub pages.'
|
58
|
+
task :publish => ['doc:pages'] do
|
59
|
+
Dir.chdir(File.dirname(__FILE__) + '/../grape.doc') do
|
60
|
+
system("git add .")
|
61
|
+
system("git add -u")
|
62
|
+
system("git commit -m 'Generating docs for version #{version}.'")
|
63
|
+
system("git push origin gh-pages")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue LoadError
|
69
|
+
puts "You need to install YARD."
|
70
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/grape.gemspec
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{grape}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Bleigh"]
|
12
|
-
s.date = %q{2010-11-
|
12
|
+
s.date = %q{2010-11-14}
|
13
13
|
s.description = %q{A Ruby framework for rapid API development with great conventions.}
|
14
14
|
s.email = %q{michael@intridea.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
"Gemfile",
|
25
25
|
"Gemfile.lock",
|
26
26
|
"LICENSE",
|
27
|
-
"README.
|
27
|
+
"README.markdown",
|
28
28
|
"Rakefile",
|
29
29
|
"VERSION",
|
30
30
|
"autotest/discover.rb",
|
data/lib/grape/api.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
require 'rack/mount'
|
2
2
|
require 'rack/auth/basic'
|
3
|
+
require 'logger'
|
3
4
|
|
4
5
|
module Grape
|
6
|
+
# The API class is the primary entry point for
|
7
|
+
# creating Grape APIs. Users should subclass this
|
8
|
+
# class in order to build an API.
|
5
9
|
class API
|
6
|
-
module Helpers; end
|
7
|
-
|
8
10
|
class << self
|
9
11
|
attr_reader :route_set
|
10
12
|
|
13
|
+
def logger
|
14
|
+
@logger ||= Logger.new($STDOUT)
|
15
|
+
end
|
16
|
+
|
11
17
|
def reset!
|
12
18
|
@settings = [{}]
|
13
19
|
@route_set = Rack::Mount::RouteSet.new
|
@@ -15,7 +21,7 @@ module Grape
|
|
15
21
|
end
|
16
22
|
|
17
23
|
def call(env)
|
18
|
-
|
24
|
+
logger.info "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
|
19
25
|
route_set.freeze.call(env)
|
20
26
|
end
|
21
27
|
|
@@ -30,6 +36,11 @@ module Grape
|
|
30
36
|
@settings
|
31
37
|
end
|
32
38
|
|
39
|
+
# Set a configuration value for this
|
40
|
+
# namespace.
|
41
|
+
#
|
42
|
+
# @param key [Symbol] The key of the configuration variable.
|
43
|
+
# @param value [Object] The value to which to set the configuration variable.
|
33
44
|
def set(key, value)
|
34
45
|
@settings.last[key.to_sym] = value
|
35
46
|
end
|
@@ -48,6 +59,9 @@ module Grape
|
|
48
59
|
new_versions.any? ? nest(block){ set(:version, new_versions) } : settings[:version]
|
49
60
|
end
|
50
61
|
|
62
|
+
# Specify the default format for the API's
|
63
|
+
# serializers. Currently only `:json` is
|
64
|
+
# supported.
|
51
65
|
def default_format(new_format = nil)
|
52
66
|
new_format ? set(:default_format, new_format.to_sym) : settings[:default_format]
|
53
67
|
end
|
@@ -76,6 +90,8 @@ module Grape
|
|
76
90
|
end
|
77
91
|
end
|
78
92
|
|
93
|
+
# Add an authentication type to the API. Currently
|
94
|
+
# only `:http_basic` is supported.
|
79
95
|
def auth(type = nil, options = {}, &block)
|
80
96
|
if type
|
81
97
|
set(:auth, {:type => type.to_sym, :proc => block}.merge(options))
|
@@ -93,47 +109,34 @@ module Grape
|
|
93
109
|
auth :http_basic, options, &block
|
94
110
|
end
|
95
111
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
-
|
109
|
-
def route(method, path_info, &block)
|
110
|
-
route_set.add_route(build_endpoint(&block),
|
111
|
-
:path_info => Rack::Mount::Strexp.compile(compile_path(path_info)),
|
112
|
-
:request_method => method
|
113
|
-
)
|
114
|
-
end
|
115
|
-
|
116
|
-
def build_endpoint(&block)
|
117
|
-
|
118
|
-
b = Rack::Builder.new
|
119
|
-
b.use Grape::Middleware::Error
|
120
|
-
b.use Rack::Auth::Basic, settings[:auth][:realm], &settings[:auth][:proc] if settings[:auth] && settings[:auth][:type] == :http_basic
|
121
|
-
b.use Grape::Middleware::Prefixer, :prefix => prefix if prefix
|
122
|
-
b.use Grape::Middleware::Versioner, :versions => (version if version.is_a?(Array)) if version
|
123
|
-
b.use Grape::Middleware::Formatter, :default_format => default_format || :json
|
124
|
-
|
125
|
-
endpoint = Grape::Endpoint.new(&block)
|
126
|
-
endpoint.send :extend, helpers
|
127
|
-
b.run endpoint
|
112
|
+
# Defines a route that will be recognized
|
113
|
+
# by the Grape API.
|
114
|
+
#
|
115
|
+
# @param methods [HTTP Verb(s)] One or more HTTP verbs that are accepted by this route. Set to `:any` if you want any verb to be accepted.
|
116
|
+
# @param paths [String(s)] One or more strings representing the URL segment(s) for this route.
|
117
|
+
# @param block [Proc] The code to be executed
|
118
|
+
def route(methods, paths, &block)
|
119
|
+
methods = Array(methods)
|
120
|
+
paths = ['/'] if paths == []
|
121
|
+
paths = Array(paths)
|
122
|
+
endpoint = build_endpoint(&block)
|
128
123
|
|
129
|
-
|
124
|
+
methods.each do |method|
|
125
|
+
paths.each do |path|
|
126
|
+
path = Rack::Mount::Strexp.compile(compile_path(path))
|
127
|
+
route_set.add_route(endpoint,
|
128
|
+
:path_info => path,
|
129
|
+
:request_method => (method.to_s.upcase unless method == :any)
|
130
|
+
)
|
131
|
+
end
|
132
|
+
end
|
130
133
|
end
|
131
134
|
|
132
|
-
def get(
|
133
|
-
def post(
|
134
|
-
def put(
|
135
|
-
def head(
|
136
|
-
def delete(
|
135
|
+
def get(*paths, &block); route('GET', paths, &block) end
|
136
|
+
def post(*paths, &block); route('POST', paths, &block) end
|
137
|
+
def put(*paths, &block); route('PUT', paths, &block) end
|
138
|
+
def head(*paths, &block); route('HEAD', paths, &block) end
|
139
|
+
def delete(*paths, &block); route('DELETE', paths, &block) end
|
137
140
|
|
138
141
|
def namespace(space = nil, &block)
|
139
142
|
if space || block_given?
|
@@ -145,6 +148,19 @@ module Grape
|
|
145
148
|
end
|
146
149
|
end
|
147
150
|
|
151
|
+
alias_method :group, :namespace
|
152
|
+
alias_method :resource, :namespace
|
153
|
+
alias_method :resources, :namespace
|
154
|
+
|
155
|
+
# Create a scope without affecting the URL.
|
156
|
+
#
|
157
|
+
# @param name [Symbol] Purely placebo, just allows to to name the scope to make the code more readable.
|
158
|
+
def scope(name = nil, &block)
|
159
|
+
nest(block)
|
160
|
+
end
|
161
|
+
|
162
|
+
protected
|
163
|
+
|
148
164
|
# Execute first the provided block, then each of the
|
149
165
|
# block passed in. Allows for simple 'before' setups
|
150
166
|
# of settings stack pushes.
|
@@ -152,7 +168,7 @@ module Grape
|
|
152
168
|
blocks.reject!{|b| b.nil?}
|
153
169
|
if blocks.any?
|
154
170
|
settings_stack << {}
|
155
|
-
instance_eval &block
|
171
|
+
instance_eval &block if block_given?
|
156
172
|
blocks.each{|b| instance_eval &b}
|
157
173
|
settings_stack.pop
|
158
174
|
else
|
@@ -160,13 +176,37 @@ module Grape
|
|
160
176
|
end
|
161
177
|
end
|
162
178
|
|
163
|
-
|
164
|
-
|
165
|
-
|
179
|
+
def build_endpoint(&block)
|
180
|
+
b = Rack::Builder.new
|
181
|
+
b.use Grape::Middleware::Error
|
182
|
+
b.use Rack::Auth::Basic, settings[:auth][:realm], &settings[:auth][:proc] if settings[:auth] && settings[:auth][:type] == :http_basic
|
183
|
+
b.use Grape::Middleware::Prefixer, :prefix => prefix if prefix
|
184
|
+
b.use Grape::Middleware::Versioner, :versions => (version if version.is_a?(Array)) if version
|
185
|
+
b.use Grape::Middleware::Formatter, :default_format => default_format || :json
|
186
|
+
|
187
|
+
endpoint = Grape::Endpoint.generate(&block)
|
188
|
+
endpoint.send :include, helpers
|
189
|
+
b.run endpoint
|
190
|
+
|
191
|
+
b.to_app
|
192
|
+
end
|
166
193
|
|
167
194
|
def inherited(subclass)
|
168
195
|
subclass.reset!
|
169
196
|
end
|
197
|
+
|
198
|
+
def route_set
|
199
|
+
@route_set ||= Rack::Mount::RouteSet.new
|
200
|
+
end
|
201
|
+
|
202
|
+
def compile_path(path)
|
203
|
+
parts = []
|
204
|
+
parts << prefix if prefix
|
205
|
+
parts << ':version' if version
|
206
|
+
parts << namespace if namespace
|
207
|
+
parts << path
|
208
|
+
Rack::Mount::Utils.normalize_path(parts.join('/'))
|
209
|
+
end
|
170
210
|
end
|
171
211
|
|
172
212
|
reset!
|
data/lib/grape/endpoint.rb
CHANGED
@@ -7,12 +7,26 @@ module Grape
|
|
7
7
|
# on the instance level of this class may be called
|
8
8
|
# from inside a `get`, `post`, etc. block.
|
9
9
|
class Endpoint
|
10
|
-
def
|
11
|
-
|
10
|
+
def self.generate(&block)
|
11
|
+
c = Class.new(Grape::Endpoint)
|
12
|
+
c.class_eval do
|
13
|
+
@block = block
|
14
|
+
end
|
15
|
+
c
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_accessor :block
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.call(env)
|
23
|
+
new.call(env)
|
12
24
|
end
|
13
25
|
|
14
26
|
attr_reader :env, :request
|
15
27
|
|
28
|
+
# The parameters passed into the request as
|
29
|
+
# well as parsed from URL segments.
|
16
30
|
def params
|
17
31
|
@params ||= request.params.merge(env['rack.routing_args'] || {}).inject({}) do |h,(k,v)|
|
18
32
|
h[k.to_s] = v
|
@@ -21,13 +35,21 @@ module Grape
|
|
21
35
|
end
|
22
36
|
end
|
23
37
|
|
38
|
+
# The API version as specified in the URL.
|
24
39
|
def version; env['api.version'] end
|
25
40
|
|
41
|
+
# End the request and display an error to the
|
42
|
+
# end user with the specified message.
|
43
|
+
#
|
44
|
+
# @param message [String] The message to display.
|
45
|
+
# @param status [Integer] the HTTP Status Code. Defaults to 403.
|
26
46
|
def error!(message, status=403)
|
27
47
|
throw :error, :message => message, :status => status
|
28
48
|
end
|
29
49
|
|
30
50
|
# Set or retrieve the HTTP status code.
|
51
|
+
#
|
52
|
+
# @param status [Integer] The HTTP Status Code to return for this request.
|
31
53
|
def status(status = nil)
|
32
54
|
if status
|
33
55
|
@status = status
|
@@ -54,10 +76,10 @@ module Grape
|
|
54
76
|
|
55
77
|
def call(env)
|
56
78
|
@env = env
|
57
|
-
@request = Rack::Request.new(@env)
|
58
79
|
@header = {}
|
80
|
+
@request = Rack::Request.new(@env)
|
59
81
|
|
60
|
-
response_text = instance_eval
|
82
|
+
response_text = instance_eval &self.class.block
|
61
83
|
|
62
84
|
[status, header, [response_text]]
|
63
85
|
end
|
data/spec/grape/api_spec.rb
CHANGED
@@ -119,7 +119,7 @@ describe Grape::API do
|
|
119
119
|
version 'v2'
|
120
120
|
compile_path('hello').should == '/:version/hello'
|
121
121
|
end
|
122
|
-
subject.compile_path
|
122
|
+
subject.send(:compile_path, 'hello').should == '/hello'
|
123
123
|
end
|
124
124
|
|
125
125
|
%w(group resource resources).each do |als|
|
@@ -149,6 +149,39 @@ describe Grape::API do
|
|
149
149
|
last_response.body.should == 'Created a Vote'
|
150
150
|
end
|
151
151
|
|
152
|
+
it 'should allow for multiple paths' do
|
153
|
+
subject.get("/abc", "/def") do
|
154
|
+
"foo"
|
155
|
+
end
|
156
|
+
|
157
|
+
get '/abc'
|
158
|
+
last_response.body.should == 'foo'
|
159
|
+
get '/def'
|
160
|
+
last_response.body.should == 'foo'
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should allow for multiple verbs' do
|
164
|
+
subject.route([:get, :post], '/abc') do
|
165
|
+
"hiya"
|
166
|
+
end
|
167
|
+
|
168
|
+
get '/abc'
|
169
|
+
last_response.body.should == 'hiya'
|
170
|
+
post '/abc'
|
171
|
+
last_response.body.should == 'hiya'
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should allow for :any as a verb' do
|
175
|
+
subject.route(:any, '/abc') do
|
176
|
+
"lol"
|
177
|
+
end
|
178
|
+
|
179
|
+
%w(get post put delete).each do |m|
|
180
|
+
send(m, '/abc')
|
181
|
+
last_response.body.should == 'lol'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
152
185
|
verbs = %w(post get head delete put)
|
153
186
|
verbs.each do |verb|
|
154
187
|
it "should allow and properly constrain a #{verb.upcase} method" do
|
@@ -280,4 +313,31 @@ describe Grape::API do
|
|
280
313
|
lambda{get '/howdy'}.should_not raise_error
|
281
314
|
end
|
282
315
|
end
|
316
|
+
|
317
|
+
describe '.scope' do
|
318
|
+
it 'should scope the various settings' do
|
319
|
+
subject.version 'v2'
|
320
|
+
|
321
|
+
subject.scope :legacy do
|
322
|
+
version 'v1'
|
323
|
+
|
324
|
+
get '/abc' do
|
325
|
+
version
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
subject.get '/def' do
|
330
|
+
version
|
331
|
+
end
|
332
|
+
|
333
|
+
get '/v2/abc'
|
334
|
+
last_response.status.should == 404
|
335
|
+
get '/v1/abc'
|
336
|
+
last_response.status.should == 200
|
337
|
+
get '/v1/def'
|
338
|
+
last_response.status.should == 404
|
339
|
+
get '/v2/def'
|
340
|
+
last_response.status.should == 200
|
341
|
+
end
|
342
|
+
end
|
283
343
|
end
|
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -72,4 +72,33 @@ describe Grape::Endpoint do
|
|
72
72
|
last_response.body.should == "Unauthorized."
|
73
73
|
end
|
74
74
|
end
|
75
|
+
|
76
|
+
it 'should not persist params between calls' do
|
77
|
+
subject.post('/new') do
|
78
|
+
params[:text]
|
79
|
+
end
|
80
|
+
|
81
|
+
post '/new', :text => 'abc'
|
82
|
+
last_response.body.should == 'abc'
|
83
|
+
|
84
|
+
post '/new', :text => 'def'
|
85
|
+
last_response.body.should == 'def'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should reset all instance variables (except block) between calls' do
|
89
|
+
subject.helpers do
|
90
|
+
def memoized
|
91
|
+
@memoized ||= params[:howdy]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
subject.get('/hello') do
|
96
|
+
memoized
|
97
|
+
end
|
98
|
+
|
99
|
+
get '/hello?howdy=hey'
|
100
|
+
last_response.body.should == 'hey'
|
101
|
+
get '/hello?howdy=yo'
|
102
|
+
last_response.body.should == 'yo'
|
103
|
+
end
|
75
104
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Bleigh
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-14 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -140,7 +140,7 @@ extensions: []
|
|
140
140
|
|
141
141
|
extra_rdoc_files:
|
142
142
|
- LICENSE
|
143
|
-
- README.
|
143
|
+
- README.markdown
|
144
144
|
files:
|
145
145
|
- .document
|
146
146
|
- .gitignore
|
@@ -149,7 +149,7 @@ files:
|
|
149
149
|
- Gemfile
|
150
150
|
- Gemfile.lock
|
151
151
|
- LICENSE
|
152
|
-
- README.
|
152
|
+
- README.markdown
|
153
153
|
- Rakefile
|
154
154
|
- VERSION
|
155
155
|
- autotest/discover.rb
|
data/README.rdoc
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
= UNDER CONSTRUCTION. DO NOT USE
|
2
|
-
|
3
|
-
= Grape
|
4
|
-
|
5
|
-
Grape is a REST-like API micro-framework for Ruby. It is built to complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily provide APIs. It has built-in support for common conventions such as multiple formats, subdomain/prefix restriction, and versioning.
|
6
|
-
|
7
|
-
class Twitter::API < Grape::Base
|
8
|
-
subdomain 'api'
|
9
|
-
version '1'
|
10
|
-
formats :xml, :json
|
11
|
-
authorization :oauth, User
|
12
|
-
|
13
|
-
resource :statuses do
|
14
|
-
group :timelines do
|
15
|
-
formats :rss, :atom
|
16
|
-
|
17
|
-
get :public_timeline do
|
18
|
-
optional :trim_user, Boolean
|
19
|
-
optional :include_entities, Boolean
|
20
|
-
|
21
|
-
Tweet.limit(20)
|
22
|
-
end
|
23
|
-
|
24
|
-
get :home_timeline do
|
25
|
-
authorized
|
26
|
-
|
27
|
-
user.home_timeline
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Rack endpoint
|
34
|
-
Twitter::API.statuses.timelines.get(:public_timeline)
|
35
|
-
|
36
|
-
class Twitter::API::User < Grape::Resource::ActiveRecord
|
37
|
-
represents ::User
|
38
|
-
|
39
|
-
property :status, lambda{|u| u.latest_status}, Twitter::API::Status
|
40
|
-
end
|
41
|
-
|
42
|
-
== Note on Patches/Pull Requests
|
43
|
-
|
44
|
-
* Fork the project.
|
45
|
-
* Make your feature addition or bug fix.
|
46
|
-
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
47
|
-
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
48
|
-
* Send me a pull request. Bonus points for topic branches.
|
49
|
-
|
50
|
-
== Copyright
|
51
|
-
|
52
|
-
Copyright (c) 2010 Michael Bleigh and Intridea, Inc. See LICENSE for details.
|