grape 0.2.6 → 0.3.0
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/{CHANGELOG.markdown → CHANGELOG.md} +21 -1
- data/Gemfile +1 -0
- data/{README.markdown → README.md} +178 -125
- data/grape.gemspec +1 -1
- data/lib/grape.rb +25 -3
- data/lib/grape/api.rb +43 -20
- data/lib/grape/endpoint.rb +32 -13
- data/lib/grape/exceptions/base.rb +50 -1
- data/lib/grape/exceptions/invalid_formatter.rb +13 -0
- data/lib/grape/exceptions/invalid_versioner_option.rb +14 -0
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +15 -0
- data/lib/grape/exceptions/missing_mime_type.rb +14 -0
- data/lib/grape/exceptions/missing_option.rb +13 -0
- data/lib/grape/exceptions/missing_vendor_option.rb +13 -0
- data/lib/grape/exceptions/unknown_options.rb +14 -0
- data/lib/grape/exceptions/unknown_validator.rb +12 -0
- data/lib/grape/exceptions/{validation_error.rb → validation.rb} +3 -1
- data/lib/grape/formatter/xml.rb +2 -1
- data/lib/grape/locale/en.yml +20 -0
- data/lib/grape/middleware/base.rb +0 -5
- data/lib/grape/middleware/error.rb +1 -2
- data/lib/grape/middleware/formatter.rb +9 -5
- data/lib/grape/middleware/versioner.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +16 -6
- data/lib/grape/middleware/versioner/param.rb +1 -1
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/util/content_types.rb +0 -2
- data/lib/grape/validations.rb +7 -14
- data/lib/grape/validations/coerce.rb +2 -1
- data/lib/grape/validations/presence.rb +2 -1
- data/lib/grape/validations/regexp.rb +2 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +150 -5
- data/spec/grape/endpoint_spec.rb +51 -157
- data/spec/grape/entity_spec.rb +142 -520
- data/spec/grape/exceptions/invalid_formatter_spec.rb +18 -0
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +18 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +24 -0
- data/spec/grape/exceptions/missing_option_spec.rb +18 -0
- data/spec/grape/exceptions/unknown_options_spec.rb +18 -0
- data/spec/grape/exceptions/unknown_validator_spec.rb +18 -0
- data/spec/grape/middleware/formatter_spec.rb +40 -34
- data/spec/grape/middleware/versioner/header_spec.rb +78 -20
- data/spec/grape/middleware/versioner/path_spec.rb +12 -8
- data/spec/grape/validations/coerce_spec.rb +1 -0
- data/spec/grape/validations/presence_spec.rb +8 -8
- data/spec/grape/validations_spec.rb +26 -3
- data/spec/spec_helper.rb +3 -6
- metadata +44 -9
- data/lib/grape/entity.rb +0 -386
@@ -1,3 +1,23 @@
|
|
1
|
+
0.3.0 (02/21/2013)
|
2
|
+
==================
|
3
|
+
|
4
|
+
* [#294](https://github.com/intridea/grape/issues/294): Extracted `Grape::Entity` into a [grape-entity](https://github.com/agileanimal/grape-entity) gem - [@agileanimal](https://github.com/agileanimal).
|
5
|
+
* [#340](https://github.com/intridea/grape/pull/339), [#342](https://github.com/intridea/grape/pull/342): Added `:cascade` option to `version` to allow disabling of rack/mount cascade behavior - [@dieb](https://github.com/dieb).
|
6
|
+
* [#333](https://github.com/intridea/grape/pull/333): Added support for validation of arrays in `params` - [@flyerhzm](https://github.com/flyerhzm).
|
7
|
+
* [#306](https://github.com/intridea/grape/issues/306): Added I18n support for all Grape exceptions - [@niedhui](https://github.com/niedhui).
|
8
|
+
* [#309](https://github.com/intridea/grape/pull/309): Added XML support to the entity presenter - [@johnnyiller](https://github.com/johnnyiller), [@dblock](http://github.com/dblock).
|
9
|
+
* [#131](https://github.com/intridea/grape/issues/131): Added instructions for Grape API reloading in Rails - [@jyn](http://github.com/jyn), [@dblock](http://github.com/dblock).
|
10
|
+
* [#317](https://github.com/intridea/grape/issues/317): Added `headers` that returns a hash of parsed HTTP request headers - [@dblock](http://github.com/dblock).
|
11
|
+
* [#332](https://github.com/intridea/grape/pull/332): `Grape::Exceptions::Validation` now contains full nested parameter names - [@alovak](https://github.com/alovak).
|
12
|
+
* [#328](https://github.com/intridea/grape/issues/328): API version can now be specified as both String and Symbol - [@dblock](http://github.com/dblock).
|
13
|
+
* [#190](https://github.com/intridea/grape/issues/190): When you add a `GET` route for a resource, a route for the `HEAD` method will also be added automatically. You can disable this behavior with `do_not_route_head!` - [@dblock](http://github.com/dblock).
|
14
|
+
* Added `do_not_route_options!`, which disables the automatic creation of the `OPTIONS` route - [@dblock](http://github.com/dblock).
|
15
|
+
* [#309](https://github.com/intridea/grape/pull/309): An XML format API will return an error instead of returning a string representation of the response if the latter cannot be converted to XML - [@dblock](http://github.com/dblock).
|
16
|
+
* A formatter that raises an exception will cause the API to return a 500 error - [@dblock](http://github.com/dblock).
|
17
|
+
* [#322](https://github.com/intridea/grape/issues/322): When returning a 406 status, Grape will include the requested format or content-type in the response body - [@dblock](http://github.com/dblock).
|
18
|
+
* [#60](https://github.com/intridea/grape/issues/60): Fix: mounting of a Grape API onto a path - [@dblock](http://github.com/dblock).
|
19
|
+
* [#335](https://github.com/intridea/grape/pull/335): Fix: request body parameters from a `PATCH` request not available in `params` - [@FreakenK](http://github.com/FreakenK).
|
20
|
+
|
1
21
|
0.2.6 (01/11/2013)
|
2
22
|
==================
|
3
23
|
|
@@ -77,7 +97,7 @@ Fixes
|
|
77
97
|
|
78
98
|
* [#186](https://github.com/intridea/grape/issues/186): Fix: helpers allow multiple calls with modules and blocks - [@ppadron](https://github.com/ppadron).
|
79
99
|
* [#188](https://github.com/intridea/grape/pull/188): Fix: multi-method routes append '(.:format)' only once - [@kainosnoema](https://github.com/kainosnoema).
|
80
|
-
* [#64](https://github.com/intridea/grape/issues/64), [#180](https://github.com/intridea/grape/pull/180): Added support to
|
100
|
+
* [#64](https://github.com/intridea/grape/issues/64), [#180](https://github.com/intridea/grape/pull/180): Added support to `GET` request bodies as parameters - [@bobbytables](https://github.com/bobbytables).
|
81
101
|
* [#175](https://github.com/intridea/grape/pull/175): Added support for API versioning based on a request parameter - [@jackcasey](https://github.com/jackcasey).
|
82
102
|
* [#168](https://github.com/intridea/grape/pull/168): Fix: Formatter can parse symbol keys in the headers hash - [@netmask](https://github.com/netmask).
|
83
103
|
* [#169](https://github.com/intridea/grape/pull/169): Silence multi_json deprecation warnings - [@whiteley](https://github.com/whiteley).
|
data/Gemfile
CHANGED
@@ -10,6 +10,11 @@ content negotiation, versioning and much more.
|
|
10
10
|
|
11
11
|
[![Build Status](https://travis-ci.org/intridea/grape.png?branch=master)](http://travis-ci.org/intridea/grape)
|
12
12
|
|
13
|
+
## Stable Release
|
14
|
+
|
15
|
+
You're reading the documentation for the next release of Grape, which should be 0.3.
|
16
|
+
The current stable release is [0.2.6](https://github.com/intridea/grape/blob/v0.2.6/README.markdown).
|
17
|
+
|
13
18
|
## Project Tracking
|
14
19
|
|
15
20
|
* [Grape Google Group](http://groups.google.com/group/ruby-grape)
|
@@ -114,7 +119,7 @@ end
|
|
114
119
|
|
115
120
|
### Rack
|
116
121
|
|
117
|
-
The above sample creates a Rack application that can be run from a rackup
|
122
|
+
The above sample creates a Rack application that can be run from a rackup `config.ru` file
|
118
123
|
with `rackup`:
|
119
124
|
|
120
125
|
```ruby
|
@@ -130,16 +135,24 @@ And would respond to the following routes:
|
|
130
135
|
PUT /statuses/:id(.json)
|
131
136
|
DELETE /statuses/:id(.json)
|
132
137
|
|
138
|
+
Grape will also automatically respond to HEAD and OPTIONS for all GET, and just OPTIONS for all other routes.
|
139
|
+
|
133
140
|
### Rails
|
134
141
|
|
135
|
-
|
142
|
+
Place API files into `app/api` and modify `application.rb`.
|
136
143
|
|
137
144
|
```ruby
|
138
|
-
|
145
|
+
config.paths.add "app/api", :glob => "**/*.rb"
|
146
|
+
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
|
139
147
|
```
|
140
148
|
|
141
|
-
|
142
|
-
|
149
|
+
Modify `config/routes`:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
mount Twitter::API => '/'
|
153
|
+
```
|
154
|
+
|
155
|
+
See below for additional code that enables reloading of API changes in development.
|
143
156
|
|
144
157
|
### Modules
|
145
158
|
|
@@ -153,10 +166,28 @@ class Twitter::API < Grape::API
|
|
153
166
|
end
|
154
167
|
```
|
155
168
|
|
169
|
+
You can also mount on a path, which is similar to using `prefix` inside the mounted API itself.
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
class Twitter::API < Grape::API
|
173
|
+
mount Twitter::APIv1 => '/v1'
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
156
177
|
## Versioning
|
157
178
|
|
158
|
-
There are three strategies in which clients can reach your API's endpoints: `:
|
159
|
-
`:
|
179
|
+
There are three strategies in which clients can reach your API's endpoints: `:path`,
|
180
|
+
`:header` and `:param`. The default strategy is `:path`.
|
181
|
+
|
182
|
+
### Path
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
version 'v1', :using => :path
|
186
|
+
```
|
187
|
+
|
188
|
+
Using this versioning strategy, clients should pass the desired version in the URL.
|
189
|
+
|
190
|
+
curl -H http://localhost:9292/v1/statuses/public_timeline
|
160
191
|
|
161
192
|
### Header
|
162
193
|
|
@@ -173,16 +204,6 @@ supplied. This behavior is similar to routing in Rails. To circumvent this defau
|
|
173
204
|
one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error
|
174
205
|
is returned when no correct `Accept` header is supplied.
|
175
206
|
|
176
|
-
### Path
|
177
|
-
|
178
|
-
```ruby
|
179
|
-
version 'v1', :using => :path
|
180
|
-
```
|
181
|
-
|
182
|
-
Using this versioning strategy, clients should pass the desired version in the URL.
|
183
|
-
|
184
|
-
curl -H http://localhost:9292/v1/statuses/public_timeline
|
185
|
-
|
186
207
|
### Param
|
187
208
|
|
188
209
|
```ruby
|
@@ -202,6 +223,7 @@ version 'v1', :using => :param, :parameter => "v"
|
|
202
223
|
|
203
224
|
curl -H http://localhost:9292/statuses/public_timeline?v=v1
|
204
225
|
|
226
|
+
|
205
227
|
## Describing Methods
|
206
228
|
|
207
229
|
You can add a description to API methods and namespaces.
|
@@ -241,6 +263,22 @@ post '/statuses' do
|
|
241
263
|
end
|
242
264
|
```
|
243
265
|
|
266
|
+
Multipart POSTs and PUTs are supported as well.
|
267
|
+
|
268
|
+
The request:
|
269
|
+
|
270
|
+
```
|
271
|
+
curl --form image_file=image.jpg http://localhost:9292/upload
|
272
|
+
```
|
273
|
+
|
274
|
+
The Grape endpoint:
|
275
|
+
|
276
|
+
```ruby
|
277
|
+
post "upload" do
|
278
|
+
# file in params[:image_file]
|
279
|
+
end
|
280
|
+
```
|
281
|
+
|
244
282
|
## Parameter Validation and Coercion
|
245
283
|
|
246
284
|
You can define validations and coercion options for your parameters using a `params` block.
|
@@ -285,6 +323,9 @@ namespace :statuses do
|
|
285
323
|
end
|
286
324
|
```
|
287
325
|
|
326
|
+
The `namespace` method has a number of aliases, including: `group`, `resource`,
|
327
|
+
`resources`, and `segment`. Use whichever reads the best for your API.
|
328
|
+
|
288
329
|
### Custom Validators
|
289
330
|
|
290
331
|
```ruby
|
@@ -339,22 +380,26 @@ end
|
|
339
380
|
|
340
381
|
## Headers
|
341
382
|
|
342
|
-
|
383
|
+
Request headers are available through the `headers` helper or from `env` in their original form.
|
343
384
|
|
344
385
|
```ruby
|
345
386
|
get do
|
346
|
-
|
347
|
-
# ...
|
387
|
+
error!('Unauthorized', 401) unless headers['Secret-Password'] == 'swordfish'
|
348
388
|
end
|
349
389
|
```
|
350
390
|
|
351
391
|
```ruby
|
352
392
|
get do
|
353
393
|
error!('Unauthorized', 401) unless env['HTTP_SECRET_PASSWORD'] == 'swordfish'
|
354
|
-
# ...
|
355
394
|
end
|
356
395
|
```
|
357
396
|
|
397
|
+
You can set a response header with `header` inside an API.
|
398
|
+
|
399
|
+
```ruby
|
400
|
+
header "X-Robots-Tag", "noindex"
|
401
|
+
```
|
402
|
+
|
358
403
|
## Routes
|
359
404
|
|
360
405
|
Optionally, you can define requirements for your named route parameters using regular
|
@@ -455,7 +500,23 @@ redirect "/statuses", :permanent => true
|
|
455
500
|
|
456
501
|
## Allowed Methods
|
457
502
|
|
458
|
-
When you add a route for a resource, a route for the
|
503
|
+
When you add a `GET` route for a resource, a route for the `HEAD`
|
504
|
+
method will also be added automatically. You can disable this
|
505
|
+
behavior with `do_not_route_head!`.
|
506
|
+
|
507
|
+
``` ruby
|
508
|
+
class API < Grape::API
|
509
|
+
|
510
|
+
do_not_route_head!
|
511
|
+
|
512
|
+
get '/example' do
|
513
|
+
# only responds to GET
|
514
|
+
end
|
515
|
+
|
516
|
+
end
|
517
|
+
```
|
518
|
+
|
519
|
+
When you add a route for a resource, a route for the `OPTIONS`
|
459
520
|
method will also be added. The response to an OPTIONS request will
|
460
521
|
include an "Allow" header listing the supported methods.
|
461
522
|
|
@@ -486,6 +547,8 @@ curl -v -X OPTIONS http://localhost:3000/rt_count
|
|
486
547
|
< Allow: OPTIONS, GET, PUT
|
487
548
|
```
|
488
549
|
|
550
|
+
You can disable this behavior with `do_not_route_options!`.
|
551
|
+
|
489
552
|
If a request for a resource is made with an unsupported HTTP method, an
|
490
553
|
HTTP 405 (Method Not Allowed) response will be returned.
|
491
554
|
|
@@ -593,6 +656,22 @@ class Twitter::API < Grape::API
|
|
593
656
|
end
|
594
657
|
```
|
595
658
|
|
659
|
+
#### Rails 3.x
|
660
|
+
|
661
|
+
When mounted inside Rails 3.x, errors like "404 Not Found" or "406 Not Acceptable" will likely be
|
662
|
+
handled and rendered by Rails handlers. For instance, accessing a nonexistent route "/api/foo"
|
663
|
+
raises a 404, which inside rails will ultimately be translated to an `ActionController::RoutingError`,
|
664
|
+
which most likely will get rendered to a HTML error page.
|
665
|
+
|
666
|
+
Most APIs will enjoy avoiding Rails exceptions and have their own exceptions reaching the client.
|
667
|
+
In that case, the `:cascade` option can be set to `false` on the versioning definition.
|
668
|
+
|
669
|
+
```ruby
|
670
|
+
version 'v1', :using => :header, :vendor => 'twitter', :cascade => false
|
671
|
+
```
|
672
|
+
|
673
|
+
The `:cascade` option can also be used with the other versioning strategies (`:param` and `:path`).
|
674
|
+
|
596
675
|
## Logging
|
597
676
|
|
598
677
|
`Grape::API` provides a `logger` method which by default will return an instance of the `Logger`
|
@@ -648,7 +727,7 @@ is determined by the request's extension, an explicit `format` parameter in the
|
|
648
727
|
string, or `Accept` header.
|
649
728
|
|
650
729
|
The following API will only respond to the JSON content-type and will not parse any other input than `application/json`,
|
651
|
-
|
730
|
+
`application/x-www-form-urlencoded`, `multipart/form-data`, `multipart/related` and `multipart/mixed`. All other requests
|
652
731
|
will fail with an HTTP 406 error code.
|
653
732
|
|
654
733
|
```ruby
|
@@ -767,89 +846,34 @@ You can invoke the above API as follows.
|
|
767
846
|
curl -X PUT -d 'data' 'http://localhost:9292/value' -H Content-Type:text/custom -v
|
768
847
|
```
|
769
848
|
|
770
|
-
##
|
849
|
+
## RESTful Model Representations
|
771
850
|
|
772
|
-
|
773
|
-
|
774
|
-
|
851
|
+
Grape supports a range of ways to present your data with some help from a generic `present` method,
|
852
|
+
which accepts two arguments: the object to be presented and the options associated with it. The options
|
853
|
+
hash may include `:with`, which defines the entity to expose.
|
775
854
|
|
776
|
-
###
|
855
|
+
### Grape Entities
|
777
856
|
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
will always be defined. The `:version` key is defined as `api.version`. The
|
782
|
-
`:collection` key is boolean, and defined as `true` if the object presented is an
|
783
|
-
array.
|
857
|
+
Add the [grape-entity](https://github.com/agileanimal/grape-entity) gem to your Gemfile.
|
858
|
+
Please refer to the [grape-entity documentation](https://github.com/agileanimal/grape-entity/blob/master/README.markdown)
|
859
|
+
for more details.
|
784
860
|
|
785
|
-
|
786
|
-
* define a list of fields which will always be exposed
|
787
|
-
* `expose SYMBOLS, HASH`
|
788
|
-
* HASH keys include `:if`, `:unless`, `:proc`, `:as`, `:using`, `:format_with`, `:documentation`
|
789
|
-
* `:if` and `:unless` accept hashes (passed during runtime) or procs (arguments are object and options)
|
790
|
-
* `expose SYMBOL, { :format_with => :formatter }`
|
791
|
-
* expose a value, formatting it first
|
792
|
-
* `:format_with` can only be applied to one exposure at a time
|
793
|
-
* `expose SYMBOL, { :as => "alias" }`
|
794
|
-
* Expose a value, changing its hash key from SYMBOL to alias
|
795
|
-
* `:as` can only be applied to one exposure at a time
|
796
|
-
* `expose SYMBOL BLOCK`
|
797
|
-
* block arguments are object and options
|
798
|
-
* expose the value returned by the block
|
799
|
-
* block can only be applied to one exposure at a time
|
861
|
+
The following example exposes statuses.
|
800
862
|
|
801
863
|
```ruby
|
802
864
|
module API
|
865
|
+
|
803
866
|
module Entities
|
804
867
|
class Status < Grape::Entity
|
805
868
|
expose :user_name
|
806
869
|
expose :text, :documentation => { :type => "string", :desc => "Status update text." }
|
807
870
|
expose :ip, :if => { :type => :full }
|
808
871
|
expose :user_type, user_id, :if => lambda{ |status, options| status.user.public? }
|
809
|
-
expose :digest { |status, options| Digest::MD5.hexdigest(
|
872
|
+
expose :digest { |status, options| Digest::MD5.hexdigest(status.txt) }
|
810
873
|
expose :replies, :using => API::Status, :as => :replies
|
811
874
|
end
|
812
875
|
end
|
813
|
-
end
|
814
|
-
|
815
|
-
module API
|
816
|
-
module Entities
|
817
|
-
class StatusDetailed < API::Entities::Status
|
818
|
-
expose :internal_id
|
819
|
-
end
|
820
|
-
end
|
821
|
-
end
|
822
|
-
```
|
823
|
-
|
824
|
-
#### Using the Exposure DSL
|
825
|
-
|
826
|
-
Grape ships with a DSL to easily define entities within the context
|
827
|
-
of an existing class:
|
828
|
-
|
829
|
-
```ruby
|
830
|
-
class Status
|
831
|
-
include Grape::Entity::DSL
|
832
|
-
|
833
|
-
entity :text, :user_id do
|
834
|
-
expose :detailed, if: :conditional
|
835
|
-
end
|
836
|
-
end
|
837
|
-
```
|
838
|
-
|
839
|
-
The above will automatically create a `Status::Entity` class and define properties on it according
|
840
|
-
to the same rules as above. If you only want to define simple exposures you don't have to supply
|
841
|
-
a block and can instead simply supply a list of comma-separated symbols.
|
842
|
-
|
843
|
-
### Using Entities
|
844
876
|
|
845
|
-
Once an entity is defined, it can be used within endpoints, by calling `present`. The `present`
|
846
|
-
method accepts two arguments, the object to be presented and the options associated with it. The
|
847
|
-
options hash must always include `:with`, which defines the entity to expose.
|
848
|
-
|
849
|
-
If the entity includes documentation it can be included in an endpoint's description.
|
850
|
-
|
851
|
-
```ruby
|
852
|
-
module API
|
853
877
|
class Statuses < Grape::API
|
854
878
|
version 'v1'
|
855
879
|
|
@@ -865,8 +889,6 @@ module API
|
|
865
889
|
end
|
866
890
|
```
|
867
891
|
|
868
|
-
### Entity Organization
|
869
|
-
|
870
892
|
In addition to separately organizing entities, it may be useful to put them as namespaced
|
871
893
|
classes underneath the model they represent.
|
872
894
|
|
@@ -883,53 +905,44 @@ end
|
|
883
905
|
```
|
884
906
|
|
885
907
|
If you organize your entities this way, Grape will automatically detect the `Entity` class and
|
886
|
-
use it to present your models. In this example, if you added `present
|
887
|
-
Grape
|
908
|
+
use it to present your models. In this example, if you added `present Status.new` to your endpoint,
|
909
|
+
Grape will automatically detect that there is a `Status::Entity` class and use that as the
|
888
910
|
representative entity. This can still be overridden by using the `:with` option or an explicit
|
889
911
|
`represents` call.
|
890
912
|
|
891
|
-
###
|
913
|
+
### Hypermedia
|
914
|
+
|
915
|
+
You can use any Hypermedia representer, including [Roar](https://github.com/apotonick/roar).
|
916
|
+
Roar renders JSON and works with the built-in Grape JSON formatter. Add `Roar::Representer::JSON`
|
917
|
+
into your models or call `to_json` explicitly in your API implementation.
|
918
|
+
|
919
|
+
### Rabl
|
892
920
|
|
893
|
-
|
894
|
-
|
895
|
-
|
921
|
+
You can use [Rabl](https://github.com/nesquena/rabl) templates with the help of the
|
922
|
+
[grape-rabl](https://github.com/LTe/grape-rabl) gem, which defines a custom Grape Rabl
|
923
|
+
formatter.
|
924
|
+
|
925
|
+
## Authentication
|
926
|
+
|
927
|
+
### Basic and Digest Auth
|
928
|
+
|
929
|
+
Grape has built-in Basic and Digest authentication.
|
896
930
|
|
897
931
|
```ruby
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
expose :field_a, :foo, :if => lambda { |object, options| object.check == "foo" }
|
902
|
-
expose :field_b, :foo, :if => lambda { |object, options| object.check == "bar" }
|
903
|
-
end
|
904
|
-
end
|
932
|
+
http_basic do |username, password|
|
933
|
+
# verify user's password here
|
934
|
+
{ 'test' => 'password1' }[username] == password
|
905
935
|
end
|
906
936
|
```
|
907
937
|
|
908
|
-
This can be problematic, when you have mixed collections. Using `respond_to?` is safer.
|
909
|
-
|
910
938
|
```ruby
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
expose :field_a, :if => lambda { |object, options| object.check == "foo" }
|
915
|
-
expose :field_b, :if => lambda { |object, options| object.check == "bar" }
|
916
|
-
expose :foo, :if => lambda { |object, options| object.respond_to?(:foo) }
|
917
|
-
end
|
918
|
-
end
|
939
|
+
http_digest({ :realm => 'Test Api', :opaque => 'app secret' }) do |username|
|
940
|
+
# lookup the user's password here
|
941
|
+
{ 'user1' => 'password1' }[username]
|
919
942
|
end
|
920
943
|
```
|
921
944
|
|
922
|
-
|
923
|
-
|
924
|
-
Although Grape ships with its own entity support, it's also possible to use it with other frameworks and renderers.
|
925
|
-
|
926
|
-
### Hypermedia
|
927
|
-
|
928
|
-
Use [Roar](https://github.com/apotonick/roar). Include `Roar::Representer::JSON` in your models or call `to_json` explicitly on representers in your API.
|
929
|
-
|
930
|
-
### Rabl
|
931
|
-
|
932
|
-
[Rabl](https://github.com/nesquena/rabl) is supported via the [grape-rabl](https://github.com/LTe/grape-rabl) gem.
|
945
|
+
Use [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2) for OAuth2 support.
|
933
946
|
|
934
947
|
## Describing and Inspecting an API
|
935
948
|
|
@@ -981,6 +994,16 @@ class ApiLogger < Grape::Middleware::Base
|
|
981
994
|
end
|
982
995
|
```
|
983
996
|
|
997
|
+
## Before and After
|
998
|
+
|
999
|
+
Execute a block before or after every API call with `before` and `after`.
|
1000
|
+
|
1001
|
+
```ruby
|
1002
|
+
before do
|
1003
|
+
header "X-Robots-Tag", "noindex"
|
1004
|
+
end
|
1005
|
+
```
|
1006
|
+
|
984
1007
|
## Anchoring
|
985
1008
|
|
986
1009
|
Grape by default anchors all request paths, which means that the request URL
|
@@ -1080,6 +1103,36 @@ RSpec.configure do |config|
|
|
1080
1103
|
}
|
1081
1104
|
end
|
1082
1105
|
```
|
1106
|
+
|
1107
|
+
## Reloading API Changes in Development
|
1108
|
+
|
1109
|
+
### Rails 3.x
|
1110
|
+
|
1111
|
+
Add API paths to `config/application.rb`.
|
1112
|
+
|
1113
|
+
```ruby
|
1114
|
+
# Auto-load API and its subdirectories
|
1115
|
+
config.paths.add "app/api", :glob => "**/*.rb"
|
1116
|
+
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
|
1117
|
+
```
|
1118
|
+
|
1119
|
+
Create `config/initializers/reload_api.rb`.
|
1120
|
+
|
1121
|
+
```ruby
|
1122
|
+
if Rails.env.development?
|
1123
|
+
api_files = Dir["#{Rails.root}/app/api/**/*.rb"]
|
1124
|
+
api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do
|
1125
|
+
Rails.application.reload_routes!
|
1126
|
+
end
|
1127
|
+
ActionDispatch::Callbacks.to_prepare do
|
1128
|
+
api_reloader.execute_if_updated
|
1129
|
+
end
|
1130
|
+
end
|
1131
|
+
```
|
1132
|
+
|
1133
|
+
See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request/4368838#4368838) for more information.
|
1134
|
+
|
1135
|
+
|
1083
1136
|
## Performance Monitoring
|
1084
1137
|
|
1085
1138
|
Grape integrates with NewRelic via the [newrelic-grape](https://github.com/flyerhzm/newrelic-grape) gem.
|