@@ -74,22 +74,25 @@ class Twitter::API < Grape::API
7474 end
7575
7676 resource :account do
77- before{ authenticate! }
77+ before { authenticate! }
7878
7979 get ' /private' do
8080 " Congratulations, you found the secret!"
8181 end
8282 end
83+
8384end
8485```
8586
8687## Mounting
8788
88- The above sample creates a Rack application that can be run from a rackup * config.ru* file:
89+ The above sample creates a Rack application that can be run from a rackup * config.ru* file
90+ with ` rackup ` :
8991
9092``` ruby
9193run Twitter ::API
9294```
95+
9396And would respond to the following routes:
9497
9598 GET /statuses/public_timeline(.json)
@@ -103,12 +106,23 @@ In a Rails application, modify *config/routes*:
103106mount Twitter ::API => " /"
104107```
105108
109+ You can mount multiple API implementations inside another one.
110+
111+ ``` ruby
112+ class Twitter ::API < Grape ::API
113+ mount Twitter ::APIv1
114+ mount Twitter ::APIv2
115+ end
116+ ```
117+
106118## Versioning
107119
108- Versioning is handled with HTTP Accept head by default, but can be configures
109- to [ use different strategies] ( https://github.com/intridea/grape/wiki/API-Versioning ) .
110- For example, to request the above with a version, you would make the following
111- request:
120+ There are two stragies in which clients can reach your API's endpoints: ` :header `
121+ and ` :path ` . The default strategy is ` :header ` .
122+
123+ version 'v1', :using => :header
124+
125+ Using this versioning strategy, clients should pass the desired version in the HTTP Accept head.
112126
113127 curl -H Accept=application/vnd.twitter-v1+json http://localhost:9292/statuses/public_timeline
114128
@@ -117,7 +131,35 @@ supplied. This behavior is similar to routing in Rails. To circumvent this defau
117131one could use the ` :strict ` option. When this option is set to ` true ` , a ` 404 Not found ` error
118132is returned when no correct Accept header is supplied.
119133
120- Serialization takes place automatically.
134+ version 'v1', :using => :path
135+
136+ Using this versioning strategy, clients should pass the desired version in the URL.
137+
138+ curl -H http://localhost:9292/v1/statuses/public_timeline
139+
140+ Serialization takes place automatically.
141+
142+ ## Parameters
143+
144+ Parameters are available through the ` params ` hash object. This includes ` GET ` and ` POST ` parameters,
145+ along with any named parameters you specify in your route strings.
146+
147+ ``` ruby
148+ get do
149+ Article .order(params[:sort_by ])
150+ end
151+ ```
152+
153+ ## Headers
154+
155+ Headers are available through the ` env ` hash object.
156+
157+ ``` ruby
158+ get do
159+ error! ' Unauthorized' , 401 unless env[' HTTP_SECRET_PASSWORD' ] == ' swordfish'
160+ ...
161+ end
162+ ```
121163
122164## Helpers
123165
@@ -244,6 +286,8 @@ class Twitter::API < Grape::API
244286end
245287```
246288
289+ Or rescue specific exceptions.
290+
247291``` ruby
248292class Twitter ::API < Grape ::API
249293 rescue_from ArgumentError do |e |
@@ -284,20 +328,42 @@ end
284328
285329## Writing Tests
286330
287- You can test a Grape API with RSpec. Tests make HTTP requests, therefore they
288- must go into the ` spec/request ` group. You may want your API code to go into
289- ` app/api ` - you can match that layout under ` spec ` by adding the following in
290- ` spec/spec_helper.rb ` .
331+ You can test a Grape API with RSpec by making HTTP requests and examining the response.
291332
292- ``` ruby
293- RSpec .configure do |config |
294- config.include RSpec ::Rails ::RequestExampleGroup , :type => :request , :example_group => {
295- :file_path => /spec\/ api/
296- }
333+ ### Writing Tests with Rack
334+
335+ Use ` rack-test ` and define your API as ` app ` .
336+
337+ ``` ruby
338+ require ' spec_helper'
339+
340+ describe Twitter ::API do
341+ include Rack ::Test ::Methods
342+
343+ def app
344+ Twitter ::API
345+ end
346+
347+ describe Twitter ::API do
348+ describe " GET /api/v1/statuses" do
349+ it " returns an empty array of statuses" do
350+ get " /api/v1/statuses"
351+ last_response.status.should == 200
352+ JSON .parse(response.body).should == []
353+ end
354+ end
355+ describe " GET /api/v1/statuses/:id" do
356+ it " returns a status by id" do
357+ status = Status .create!
358+ get " /api/v1/statuses/#{ status.id } "
359+ last_resonse.body.should == status.to_json
360+ end
361+ end
362+ end
297363end
298364```
299365
300- A simple RSpec API test makes a ` get ` request and parses the response.
366+ ### Writing Tests with Rails
301367
302368``` ruby
303369require ' spec_helper'
@@ -310,6 +376,24 @@ describe Twitter::API do
310376 JSON .parse(response.body).should == []
311377 end
312378 end
379+ describe " GET /api/v1/statuses/:id" do
380+ it " returns a status by id" do
381+ status = Status .create!
382+ get " /api/v1/statuses/#{ status.id } "
383+ resonse.body.should == status.to_json
384+ end
385+ end
386+ end
387+ ```
388+
389+ In Rails, HTTP request tests would go into the ` spec/request ` group. You may want your API code to go into
390+ ` app/api ` - you can match that layout under ` spec ` by adding the following in ` spec/spec_helper.rb ` .
391+
392+ ``` ruby
393+ RSpec .configure do |config |
394+ config.include RSpec ::Rails ::RequestExampleGroup , :type => :request , :example_group => {
395+ :file_path => /spec\/ api/
396+ }
313397end
314398```
315399
0 commit comments