Skip to content

Commit e33b8c1

Browse files
author
Michael Bleigh
committed
Add fenced and highlighted code to README
1 parent ceee711 commit e33b8c1

File tree

1 file changed

+134
-108
lines changed

1 file changed

+134
-108
lines changed

README.markdown

Lines changed: 134 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -8,176 +8,202 @@ Grape is a REST-like API micro-framework for Ruby. It is built to complement exi
88
Grape is available as a gem, to install it just install the gem:
99

1010
gem install grape
11-
11+
1212
## Basic Usage
1313

1414
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.
1515

16-
class Twitter::API < Grape::API
17-
version '1'
18-
19-
helpers do
20-
def current_user
21-
@current_user ||= User.authorize!(env)
22-
end
23-
24-
def authenticate!
25-
error!('401 Unauthorized', 401) unless current_user
26-
end
27-
end
28-
29-
resource :statuses do
30-
get :public_timeline do
31-
Tweet.limit(20)
32-
end
33-
34-
get :home_timeline do
35-
authenticate!
36-
current_user.home_timeline
37-
end
38-
39-
get '/show/:id' do
40-
Tweet.find(params[:id])
41-
end
42-
43-
post :update do
44-
authenticate!
45-
Tweet.create(
46-
:user => current_user,
47-
:text => params[:status]
48-
)
49-
end
50-
end
51-
52-
resource :account do
53-
before{ authenticate! }
54-
55-
get '/private' do
56-
"Congratulations, you found the secret!"
57-
end
58-
end
16+
```ruby
17+
class Twitter::API < Grape::API
18+
version '1'
19+
20+
helpers do
21+
def current_user
22+
@current_user ||= User.authorize!(env)
23+
end
24+
25+
def authenticate!
26+
error!('401 Unauthorized', 401) unless current_user
27+
end
28+
end
29+
30+
resource :statuses do
31+
get :public_timeline do
32+
Tweet.limit(20)
33+
end
34+
35+
get :home_timeline do
36+
authenticate!
37+
current_user.home_timeline
38+
end
39+
40+
get '/show/:id' do
41+
Tweet.find(params[:id])
42+
end
43+
44+
post :update do
45+
authenticate!
46+
Tweet.create(
47+
:user => current_user,
48+
:text => params[:status]
49+
)
50+
end
51+
end
52+
53+
resource :account do
54+
before{ authenticate! }
55+
56+
get '/private' do
57+
"Congratulations, you found the secret!"
5958
end
60-
59+
end
60+
end
61+
```
62+
6163
This would create a Rack application that could be used like so (in a Rackup config.ru file):
6264

63-
run Twitter::API
64-
65+
```ruby
66+
run Twitter::API
67+
```
68+
6569
And would respond to the following routes:
6670

6771
GET /1/statuses/public_timeline(.json)
6872
GET /1/statuses/home_timeline(.json)
6973
GET /1/statuses/show/:id(.json)
7074
POST /1/statuses/update(.json)
71-
75+
7276
Serialization takes place automatically. For more detailed usage information, please visit the [Grape Wiki](http://github.com/intridea/grape/wiki).
73-
77+
7478
## Raising Errors
7579

7680
You can raise errors explicitly.
7781

78-
error!("Access Denied", 401)
82+
```ruby
83+
error!("Access Denied", 401)
84+
```
7985

8086
You can also return JSON formatted objects explicitly by raising error! and passing a hash instead of a message.
8187

82-
error!({ "error" => "unexpected error", "detail" => "missing widget" }, 500)
88+
```ruby
89+
error!({ "error" => "unexpected error", "detail" => "missing widget" }, 500)
90+
```
8391

8492
## Exception Handling
8593

86-
Grape can be told to rescue all exceptions and instead return them in text or json formats.
94+
Grape can be told to rescue all exceptions and instead return them in
95+
text or json formats.
8796

88-
class Twitter::API < Grape::API
89-
rescue_from :all
90-
end
97+
```ruby
98+
class Twitter::API < Grape::API
99+
rescue_from :all
100+
end
101+
```
91102

92103
You can also rescue specific exceptions.
93104

94-
class Twitter::API < Grape::API
95-
rescue_from ArgumentError, NotImplementedError
96-
end
105+
```ruby
106+
class Twitter::API < Grape::API
107+
rescue_from ArgumentError, NotImplementedError
108+
end
109+
```
97110

98111
The error format can be specified using `error_format`. Available formats are `:json` and `:txt` (default).
99112

100-
class Twitter::API < Grape::API
101-
error_format :json
102-
end
113+
```ruby
114+
class Twitter::API < Grape::API
115+
error_format :json
116+
end
117+
```
103118

104119
You can rescue all exceptions with a code block. The `rack_response` wrapper automatically sets the default error code and content-type.
105120

106-
class Twitter::API < Grape::API
107-
rescue_from :all do |e|
108-
rack_response({ :message => "rescued from #{e.class.name}" })
109-
end
110-
end
121+
```ruby
122+
class Twitter::API < Grape::API
123+
rescue_from :all do |e|
124+
rack_response({ :message => "rescued from #{e.class.name}" })
125+
end
126+
end
127+
```
111128

112129
You can also rescue specific exceptions with a code block and handle the Rack response at the lowest level.
113130

114-
class Twitter::API < Grape::API
115-
rescue_from :all do |e|
116-
Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish
117-
end
118-
end
131+
```ruby
132+
class Twitter::API < Grape::API
133+
rescue_from :all do |e|
134+
Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish
135+
end
136+
end
137+
```
119138

120139
## Writing Tests
121140

122141
You can test a Grape API with RSpec. Tests make HTTP requests, therefore they must go into the `spec/request` group. You may want your API code to go into `app/api` - you can match that layout under `spec` by adding the following in `spec/spec_helper.rb`.
123142

124-
RSpec.configure do |config|
125-
config.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
126-
:file_path => /spec\/api/
127-
}
128-
end
143+
```ruby
144+
RSpec.configure do |config|
145+
config.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
146+
:file_path => /spec\/api/
147+
}
148+
end
149+
```
129150

130151
A simple RSpec API test makes a `get` request and parses the response.
131152

132-
require 'spec_helper'
153+
```ruby
154+
require 'spec_helper'
133155

134-
describe Twitter::API do
135-
describe "GET /api/v1/statuses" do
136-
it "returns an empty array of statuses" do
137-
get "/api/v1/statuses"
138-
response.status.should == 200
139-
JSON.parse(response.body).should == []
140-
end
141-
end
156+
describe Twitter::API do
157+
describe "GET /api/v1/statuses" do
158+
it "returns an empty array of statuses" do
159+
get "/api/v1/statuses"
160+
response.status.should == 200
161+
JSON.parse(response.body).should == []
142162
end
163+
end
164+
end
165+
```
143166

144167
## Inspecting an API
145168

146169
Grape exposes arrays of API versions and compiled routes. Each route contains a `route_prefix`, `route_version`, `route_namespace`, `route_method`, `route_path` and `route_params`.
147170

148-
class TwitterAPI < Grape::API
171+
```ruby
172+
class TwitterAPI < Grape::API
149173

150-
version 'v1'
151-
get "version" do
152-
api.version
153-
end
154-
155-
version 'v2'
156-
namespace "ns" do
157-
get "version" do
158-
api.version
159-
end
160-
end
174+
version 'v1'
175+
get "version" do
176+
api.version
177+
end
161178

179+
version 'v2'
180+
namespace "ns" do
181+
get "version" do
182+
api.version
162183
end
184+
end
185+
end
163186

164-
TwitterAPI::versions # yields [ 'v1', 'v2' ]
165-
TwitterAPI::routes # yields an array of Grape::Route objects
166-
TwitterAPI::routes[0].route_version # yields 'v1'
187+
TwitterAPI::versions # yields [ 'v1', 'v2' ]
188+
TwitterAPI::routes # yields an array of Grape::Route objects
189+
TwitterAPI::routes[0].route_version # yields 'v1'
190+
```
167191

168192
Grape also supports storing additional parameters with the route information. This can be useful for generating documentation. The optional hash that follows the API path may contain any number of keys and its values are also accessible via a dynamically-generated `route_[name]` function.
169193

170-
class StringAPI < Grape::API
171-
get "split/:string", { :params => [ "token" ], :optional_params => [ "limit" ] } do
172-
params[:string].split(params[:token], (params[:limit] || 0))
173-
end
174-
end
194+
```ruby
195+
class StringAPI < Grape::API
196+
get "split/:string", { :params => [ "token" ], :optional_params => [ "limit" ] } do
197+
params[:string].split(params[:token], (params[:limit] || 0))
198+
end
199+
end
175200

176-
StringAPI::routes[0].route_params # yields an array [ "string", "token" ]
177-
StringAPI::routes[0].route_optional_params # yields an array [ "limit" ]
201+
StringAPI::routes[0].route_params # yields an array [ "string", "token" ]
202+
StringAPI::routes[0].route_optional_params # yields an array [ "limit" ]
203+
```
178204

179205
## Note on Patches/Pull Requests
180-
206+
181207
* Fork the project.
182208
* Make your feature addition or bug fix.
183209
* Add tests for it. This is important so I don't break it in a future version unintentionally.

0 commit comments

Comments
 (0)