grape 0.7.0 → 0.8.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.
- checksums.yaml +5 -13
- data/.rubocop.yml +6 -6
- data/.travis.yml +11 -2
- data/CHANGELOG.md +23 -1
- data/Gemfile +11 -10
- data/Guardfile +5 -6
- data/README.md +194 -13
- data/UPGRADING.md +3 -3
- data/grape.gemspec +1 -1
- data/grape.png +0 -0
- data/lib/grape/api.rb +21 -13
- data/lib/grape/endpoint.rb +31 -13
- data/lib/grape/exceptions/validation.rb +2 -2
- data/lib/grape/locale/en.yml +2 -0
- data/lib/grape/middleware/auth/oauth2.rb +69 -65
- data/lib/grape/middleware/error.rb +4 -2
- data/lib/grape/middleware/formatter.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +3 -3
- data/lib/grape/util/hash_stack.rb +1 -1
- data/lib/grape/validations.rb +22 -8
- data/lib/grape/validations/default.rb +1 -1
- data/lib/grape/validations/exactly_one_of.rb +26 -0
- data/lib/grape/validations/mutual_exclusion.rb +25 -0
- data/lib/grape/validations/presence.rb +1 -1
- data/lib/grape/validations/regexp.rb +2 -1
- data/lib/grape/validations/values.rb +7 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +390 -333
- data/spec/grape/endpoint_spec.rb +129 -99
- data/spec/grape/entity_spec.rb +47 -27
- data/spec/grape/exceptions/invalid_formatter_spec.rb +1 -1
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -1
- data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -1
- data/spec/grape/exceptions/unknown_options_spec.rb +1 -1
- data/spec/grape/exceptions/unknown_validator_spec.rb +1 -1
- data/spec/grape/middleware/auth/basic_spec.rb +3 -3
- data/spec/grape/middleware/auth/digest_spec.rb +4 -4
- data/spec/grape/middleware/auth/oauth2_spec.rb +11 -11
- data/spec/grape/middleware/base_spec.rb +9 -9
- data/spec/grape/middleware/error_spec.rb +4 -4
- data/spec/grape/middleware/exception_spec.rb +17 -17
- data/spec/grape/middleware/formatter_spec.rb +38 -38
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +11 -11
- data/spec/grape/middleware/versioner/header_spec.rb +39 -39
- data/spec/grape/middleware/versioner/param_spec.rb +10 -10
- data/spec/grape/middleware/versioner/path_spec.rb +7 -7
- data/spec/grape/middleware/versioner_spec.rb +4 -4
- data/spec/grape/path_spec.rb +6 -6
- data/spec/grape/util/hash_stack_spec.rb +22 -22
- data/spec/grape/validations/coerce_spec.rb +34 -34
- data/spec/grape/validations/default_spec.rb +16 -16
- data/spec/grape/validations/exactly_one_of_spec.rb +71 -0
- data/spec/grape/validations/mutual_exclusion_spec.rb +61 -0
- data/spec/grape/validations/presence_spec.rb +34 -34
- data/spec/grape/validations/regexp_spec.rb +11 -4
- data/spec/grape/validations/values_spec.rb +34 -20
- data/spec/grape/validations_spec.rb +300 -147
- data/spec/shared/versioning_examples.rb +18 -18
- data/spec/spec_helper.rb +2 -1
- metadata +81 -38
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NmMwYmIxODY2ZmI0YzY5MzljYTM0NWE5MDM4MzAwZDQ3M2Y4MmYwNg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 16ab2241d8805f0449737830d3fb60b5ecf6a1e3
|
4
|
+
data.tar.gz: b2d2d3cce8167bac238d0d8ac770edac583b0a81
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NzEwNjdjYjI0MzkzNzE1M2QwM2ExZGM2NDRlMmFlNDJlZWY3NjljMGMxN2Zm
|
11
|
-
OWNkMGM0ZGFkMDQwYzk1MDBlNDZkNjI4ZmJmZjM4M2Y3MmU4NDI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
N2Y5Y2NhNWQxMjNmYmZmMzJhZDQyMzE2NDY1ODRlNjVhNDc2ZjQxNTE4NjRl
|
14
|
-
YzczZTk5NGUwZGQ1ZmJiNTUwNmQ5MTM1ZWVkNzA0M2JlNDZhNGVkM2MyNTM5
|
15
|
-
Zjg2MzhkNGI5YjMxNzRlNWUyZDg1YzA2NjY4MjdkMWE4MTU1N2Y=
|
6
|
+
metadata.gz: ead66bb7118fdb6c173dcb4e9459a6385cd1ea984738e60c23754ff1c508d8562ff8d0a161ac7bebd14ec9afc22fd73170b7f15324facfc1ce79e6688d0a2d5b
|
7
|
+
data.tar.gz: 10be3eceb5dcd72fcf5952d4d8bac3fa0eb9eb1a3eb5f08fa14486a2e24dcf21b578886dc314f09b6227d12214fa8ba9326f488405e2082acf1397e397d24d88
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
2
|
+
Exclude:
|
3
3
|
- vendor/**
|
4
4
|
- bin/**
|
5
5
|
|
@@ -24,11 +24,6 @@ Encoding:
|
|
24
24
|
# no need to always specify encoding
|
25
25
|
Enabled: false
|
26
26
|
|
27
|
-
HashMethods:
|
28
|
-
# key? instead of has_key?
|
29
|
-
# value? instead of has_value?
|
30
|
-
Enabled: false
|
31
|
-
|
32
27
|
StringLiterals:
|
33
28
|
# use single or double-quoted strings, as you please
|
34
29
|
Enabled: false
|
@@ -68,3 +63,8 @@ WordArray:
|
|
68
63
|
CyclomaticComplexity:
|
69
64
|
Enabled: false
|
70
65
|
|
66
|
+
DoubleNegation:
|
67
|
+
Enabled: false
|
68
|
+
|
69
|
+
PredicateName:
|
70
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
language: ruby
|
2
|
+
|
2
3
|
cache: bundler
|
3
|
-
|
4
|
-
- gem install bundler -v '= 1.5.1'
|
4
|
+
|
5
5
|
rvm:
|
6
|
+
- ruby-head
|
7
|
+
- 2.1.2
|
6
8
|
- 2.1.0
|
7
9
|
- 2.0.0
|
8
10
|
- 1.9.3
|
9
11
|
- jruby-19mode
|
12
|
+
- jruby-head
|
13
|
+
- rbx-2
|
14
|
+
|
15
|
+
matrix:
|
16
|
+
allow_failures:
|
17
|
+
- rvm: ruby-head
|
18
|
+
- rvm: jruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,29 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0 (7/10/2014)
|
2
2
|
=================
|
3
3
|
|
4
4
|
#### Features
|
5
|
+
|
6
|
+
* [#639](https://github.com/intridea/grape/pull/639): Added support for blocks with reusable params - [@mibon](https://github.com/mibon).
|
7
|
+
* [#637](https://github.com/intridea/grape/pull/637): Added 'exactly_one_of' validation - [@Morred](https://github.com/Morred).
|
8
|
+
* [#626](https://github.com/intridea/grape/pull/626): Mutually exclusive params - [@oliverbarnes](https://github.com/oliverbarnes).
|
9
|
+
* [#617](https://github.com/intridea/grape/pull/617): Running tests on Ruby 2.1.1, Rubinius 2.1 and 2.2, Ruby and JRuby HEAD - [@dblock](https://github.com/dblock).
|
10
|
+
* [#397](https://github.com/intridea/grape/pull/397): Adds `Grape::Endpoint.before_each` to allow easy helper stubbing - [@mbleigh](https://github.com/mbleigh).
|
11
|
+
* [#673](https://github.com/intridea/grape/pull/673): Avoid requiring non-existent fields when using Grape::Entity documentation - [@qqshfox](https://github.com/qqshfox).
|
12
|
+
|
13
|
+
#### Fixes
|
14
|
+
|
15
|
+
* [#671](https://github.com/intridea/grape/pull/671): Allow required param with predefined set of values to be nil inside optional group - [@dm1try](https://github.com/dm1try).
|
16
|
+
* [#651](https://github.com/intridea/grape/pull/651): The `rescue_from` keyword now properly defaults to rescuing subclasses of exceptions - [@xevix](https://github.com/xevix).
|
17
|
+
* [#614](https://github.com/intridea/grape/pull/614): Params with `nil` value are now refused by `RegexpValidator` - [@dm1try](https://github.com/dm1try).
|
18
|
+
* [#494](https://github.com/intridea/grape/issues/494): Fixed performance issue with requests carrying a large payload - [@dblock](https://github.com/dblock).
|
19
|
+
* [#619](https://github.com/intridea/grape/pull/619): Convert specs to RSpec 3 syntax with Transpec - [@danielspector](https://github.com/danielspector).
|
20
|
+
* [#632](https://github.com/intridea/grape/pull/632): `Grape::Endpoint#present` causes ActiveRecord to make an extra query during entity's detection - [@fixme](https://github.com/fixme).
|
21
|
+
|
22
|
+
0.7.0 (4/2/2014)
|
23
|
+
=================
|
24
|
+
|
25
|
+
#### Features
|
26
|
+
|
5
27
|
* [#558](https://github.com/intridea/grape/pull/558): Support lambda-based values for params - [@wpschallenger](https://github.com/wpschallenger).
|
6
28
|
* [#510](https://github.com/intridea/grape/pull/510): Support lambda-based default values for params - [@myitcv](https://github.com/myitcv).
|
7
29
|
* [#511](https://github.com/intridea/grape/pull/511): Added `required` option for OAuth2 middleware - [@bcm](https://github.com/bcm).
|
data/Gemfile
CHANGED
@@ -3,18 +3,19 @@ source 'http://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :development, :test do
|
6
|
-
gem 'pry'
|
7
|
-
gem 'guard'
|
8
|
-
gem 'guard-rspec'
|
9
|
-
gem 'guard-bundler'
|
10
|
-
gem 'rb-fsevent'
|
11
|
-
gem 'growl'
|
12
|
-
gem 'json'
|
13
6
|
gem 'rspec', '~> 2.14.1'
|
14
7
|
gem 'rack-test', '~> 0.6.2', require: 'rack/test'
|
15
|
-
gem 'github-markup'
|
16
8
|
gem 'cookiejar'
|
17
9
|
gem 'rack-contrib'
|
18
|
-
gem '
|
19
|
-
gem '
|
10
|
+
gem 'rubocop', '~> 0.20.1'
|
11
|
+
gem 'guard'
|
12
|
+
gem 'guard-rspec'
|
13
|
+
gem 'guard-rubocop'
|
14
|
+
gem 'mime-types'
|
15
|
+
end
|
16
|
+
|
17
|
+
platforms :rbx do
|
18
|
+
gem 'rubysl'
|
19
|
+
gem 'rubinius-developer_tools'
|
20
|
+
gem 'racc'
|
20
21
|
end
|
data/Guardfile
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard
|
4
|
+
guard :rspec do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
-
watch(
|
8
|
-
watch('spec/spec_helper.rb') { "spec/" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
9
8
|
end
|
10
9
|
|
11
10
|
|
12
|
-
guard
|
13
|
-
watch(
|
14
|
-
watch(
|
11
|
+
guard :rubocop do
|
12
|
+
watch(%r{.+\.rb$})
|
13
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
15
14
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,70 @@
|
|
1
|
-
![grape logo](
|
1
|
+
![grape logo](grape.png)
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/intridea/grape.png?branch=master)](http://travis-ci.org/intridea/grape) [![Code Climate](https://codeclimate.com/github/intridea/grape.png)](https://codeclimate.com/github/intridea/grape) [![Inline docs](http://inch-ci.org/github/intridea/grape.png)](http://inch-ci.org/github/intridea/grape) [![Dependency Status](https://www.versioneye.com/ruby/grape/0.7.0/badge.png)](https://www.versioneye.com/ruby/grape/0.7.0)
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
- [What is Grape?](#what-is-grape)
|
8
|
+
- [Stable Release](#stable-release)
|
9
|
+
- [Project Resources](#project-resources)
|
10
|
+
- [Installation](#installation)
|
11
|
+
- [Basic Usage](#basic-usage)
|
12
|
+
- [Mounting](#mounting)
|
13
|
+
- [Rack](#rack)
|
14
|
+
- [Alongside Sinatra (or other frameworks)](#alongside-sinatra-or-other-frameworks)
|
15
|
+
- [Rails](#rails)
|
16
|
+
- [Modules](#modules)
|
17
|
+
- [Versioning](#versioning)
|
18
|
+
- [Path](#path)
|
19
|
+
- [Header](#header)
|
20
|
+
- [Accept-Version Header](#accept-version-header)
|
21
|
+
- [Param](#param)
|
22
|
+
- [Describing Methods](#describing-methods)
|
23
|
+
- [Parameters](#parameters)
|
24
|
+
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
|
25
|
+
- [Namespace Validation and Coercion](#namespace-validation-and-coercion)
|
26
|
+
- [Custom Validators](#custom-validators)
|
27
|
+
- [Validation Errors](#validation-errors)
|
28
|
+
- [I18n](#i18n)
|
29
|
+
- [Headers](#headers)
|
30
|
+
- [Routes](#routes)
|
31
|
+
- [Helpers](#helpers)
|
32
|
+
- [Parameter Documentation](#parameter-documentation)
|
33
|
+
- [Cookies](#cookies)
|
34
|
+
- [Redirecting](#redirecting)
|
35
|
+
- [Allowed Methods](#allowed-methods)
|
36
|
+
- [Raising Exceptions](#raising-exceptions)
|
37
|
+
- [Default Error HTTP Status Code](#default-error-http-status-code)
|
38
|
+
- [Handling 404](#handling-404)
|
39
|
+
- [Exception Handling](#exception-handling)
|
40
|
+
- [Rails 3.x](#rails-3x)
|
41
|
+
- [Logging](#logging)
|
42
|
+
- [API Formats](#api-formats)
|
43
|
+
- [JSONP](#jsonp)
|
44
|
+
- [CORS](#cors)
|
45
|
+
- [Content-type](#content-type)
|
46
|
+
- [API Data Formats](#api-data-formats)
|
47
|
+
- [RESTful Model Representations](#restful-model-representations)
|
48
|
+
- [Grape Entities](#grape-entities)
|
49
|
+
- [Hypermedia](#hypermedia)
|
50
|
+
- [Rabl](#rabl)
|
51
|
+
- [Active Model Serializers](#active-model-serializers)
|
52
|
+
- [Authentication](#authentication)
|
53
|
+
- [Describing and Inspecting an API](#describing-and-inspecting-an-api)
|
54
|
+
- [Current Route and Endpoint](#current-route-and-endpoint)
|
55
|
+
- [Before and After](#before-and-after)
|
56
|
+
- [Anchoring](#anchoring)
|
57
|
+
- [Writing Tests](#writing-tests)
|
58
|
+
- [Writing Tests with Rack](#writing-tests-with-rack)
|
59
|
+
- [Writing Tests with Rails](#writing-tests-with-rails)
|
60
|
+
- [Stubbing Helpers](#stubbing-helpers)
|
61
|
+
- [Reloading API Changes in Development](#reloading-api-changes-in-development)
|
62
|
+
- [Rails 3.x](#rails-3x)
|
63
|
+
- [Performance Monitoring](#performance-monitoring)
|
64
|
+
- [Contributing to Grape](#contributing-to-grape)
|
65
|
+
- [Hacking on Grape](#hacking-on-grape)
|
66
|
+
- [License](#license)
|
67
|
+
- [Copyright](#copyright)
|
2
68
|
|
3
69
|
## What is Grape?
|
4
70
|
|
@@ -8,11 +74,10 @@ providing a simple DSL to easily develop RESTful APIs. It has built-in support
|
|
8
74
|
for common conventions, including multiple formats, subdomain/prefix restriction,
|
9
75
|
content negotiation, versioning and much more.
|
10
76
|
|
11
|
-
[![Build Status](https://travis-ci.org/intridea/grape.png?branch=master)](http://travis-ci.org/intridea/grape) [![Code Climate](https://codeclimate.com/github/intridea/grape.png)](https://codeclimate.com/github/intridea/grape) [![Inline docs](http://inch-pages.github.io/github/intridea/grape.png)](http://inch-pages.github.io/github/intridea/grape) [![Dependency Status](https://www.versioneye.com/ruby/grape/0.6.1/badge.png)](https://www.versioneye.com/ruby/grape/0.6.1)
|
12
|
-
|
13
77
|
## Stable Release
|
14
78
|
|
15
|
-
You're reading the documentation for the stable release of Grape, 0.
|
79
|
+
You're reading the documentation for the stable release of Grape, 0.8.0.
|
80
|
+
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
16
81
|
|
17
82
|
## Project Resources
|
18
83
|
|
@@ -164,7 +229,9 @@ run Rack::Cascade.new [API, Web]
|
|
164
229
|
|
165
230
|
### Rails
|
166
231
|
|
167
|
-
Place API files into `app/api
|
232
|
+
Place API files into `app/api`. Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class. In our example, the file name location and directory for `Twitter::API` should be `app/api/twitter/api.rb`.
|
233
|
+
|
234
|
+
Modify `application.rb`:
|
168
235
|
|
169
236
|
```ruby
|
170
237
|
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
|
@@ -345,6 +412,7 @@ params do
|
|
345
412
|
optional :audio do
|
346
413
|
requires :format, type: Symbol, values: [:mp3, :wav, :aac, :ogg], default: :mp3
|
347
414
|
end
|
415
|
+
mutually_exclusive :media, :audio
|
348
416
|
end
|
349
417
|
put ':id' do
|
350
418
|
# params[:id] is an Integer
|
@@ -406,6 +474,41 @@ params do
|
|
406
474
|
end
|
407
475
|
```
|
408
476
|
|
477
|
+
Parameters can be defined as `mutually_exclusive`, ensuring that they aren't present at the same time in a request.
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
params do
|
481
|
+
optional :beer
|
482
|
+
optional :wine
|
483
|
+
mutually_exclusive :beer, :wine
|
484
|
+
end
|
485
|
+
```
|
486
|
+
|
487
|
+
Multiple sets can be defined:
|
488
|
+
|
489
|
+
```ruby
|
490
|
+
params do
|
491
|
+
optional :beer
|
492
|
+
optional :wine
|
493
|
+
mutually_exclusive :beer, :wine
|
494
|
+
optional :scotch
|
495
|
+
optional :aquavit
|
496
|
+
mutually_exclusive :scotch, :aquavit
|
497
|
+
end
|
498
|
+
```
|
499
|
+
|
500
|
+
**Warning**: Never define mutually exclusive sets with any required params. Two mutually exclusive required params will mean params are never valid, thus making the endpoint useless. One required param mutually exclusive with an optional param will mean the latter is never valid.
|
501
|
+
|
502
|
+
Parameters can be defined as 'exactly_one_of', ensuring that exactly one parameter gets selected.
|
503
|
+
|
504
|
+
```ruby
|
505
|
+
params do
|
506
|
+
optional :beer
|
507
|
+
optional :wine
|
508
|
+
exactly_one_of :beer, :wine
|
509
|
+
end
|
510
|
+
```
|
511
|
+
|
409
512
|
### Namespace Validation and Coercion
|
410
513
|
|
411
514
|
Namespaces allow parameter definitions and apply to every method within the namespace.
|
@@ -624,13 +727,43 @@ end
|
|
624
727
|
class API < Grape::API
|
625
728
|
helpers SharedParams
|
626
729
|
|
627
|
-
desc "Get collection"
|
730
|
+
desc "Get collection."
|
628
731
|
params do
|
629
732
|
use :period, :pagination
|
630
733
|
end
|
734
|
+
|
631
735
|
get do
|
632
|
-
Collection
|
633
|
-
|
736
|
+
Collection
|
737
|
+
.from(params[:start_date])
|
738
|
+
.to(params[:end_date])
|
739
|
+
.page(params[:page])
|
740
|
+
.per(params[:per_page])
|
741
|
+
end
|
742
|
+
end
|
743
|
+
```
|
744
|
+
|
745
|
+
Helpers support blocks that can help set default values. The following API can return a collection sorted by `id` or `created_at` in `asc` or `desc` order.
|
746
|
+
|
747
|
+
```ruby
|
748
|
+
module SharedParams
|
749
|
+
extend Grape::API::Helpers
|
750
|
+
|
751
|
+
params :order do |options|
|
752
|
+
optional :order_by, type:Symbol, values:options[:order_by], default:options[:default_order_by]
|
753
|
+
optional :order, type:Symbol, values:%i(asc desc), default:options[:default_order]
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
class API < Grape::API
|
758
|
+
helpers SharedParams
|
759
|
+
|
760
|
+
desc "Get a sorted collection."
|
761
|
+
params do
|
762
|
+
use :order, order_by:%i(id created_at), default_order_by: :created_at, default_order: :asc
|
763
|
+
end
|
764
|
+
|
765
|
+
get do
|
766
|
+
Collection.send(params[:order], params[:order_by])
|
634
767
|
end
|
635
768
|
end
|
636
769
|
```
|
@@ -911,7 +1044,7 @@ The code below will rescue exceptions of type `RuntimeError` but _not_ its subcl
|
|
911
1044
|
|
912
1045
|
```ruby
|
913
1046
|
rescue_from RuntimeError, rescue_subclasses: false do |e|
|
914
|
-
Rack::Response.new(
|
1047
|
+
Rack::Response.new({
|
915
1048
|
status: e.status,
|
916
1049
|
message: e.message,
|
917
1050
|
errors: e.errors
|
@@ -1072,6 +1205,21 @@ The order for choosing the format is the following.
|
|
1072
1205
|
* Use the default format, if specified by the `default_format` option.
|
1073
1206
|
* Default to `:txt`.
|
1074
1207
|
|
1208
|
+
You can override this process explicitly by specifying `env['api.format']` in the API itself.
|
1209
|
+
For example, the following API will let you upload arbitrary files and return their contents as an attachment with the correct MIME type.
|
1210
|
+
|
1211
|
+
```ruby
|
1212
|
+
class Twitter::API < Grape::API
|
1213
|
+
post "attachment" do
|
1214
|
+
filename = params[:file][:filename]
|
1215
|
+
content_type MIME::Types.type_for(filename)[0].to_s
|
1216
|
+
env['api.format'] = :binary # there's no formatter for :binary, data will be returned "as is"
|
1217
|
+
header "Content-Disposition", "attachment; filename*=UTF-8''#{URI.escape(filename)}"
|
1218
|
+
params[:file][:tempfile].read
|
1219
|
+
end
|
1220
|
+
end
|
1221
|
+
```
|
1222
|
+
|
1075
1223
|
### JSONP
|
1076
1224
|
|
1077
1225
|
Grape supports JSONP via [Rack::JSONP](https://github.com/rack/rack-contrib), part of the
|
@@ -1183,7 +1331,7 @@ module API
|
|
1183
1331
|
expose :user_name
|
1184
1332
|
expose :text, documentation: { type: "string", desc: "Status update text." }
|
1185
1333
|
expose :ip, if: { type: :full }
|
1186
|
-
expose :user_type, user_id, if: lambda { |status, options| status.user.public? }
|
1334
|
+
expose :user_type, :user_id, if: lambda { |status, options| status.user.public? }
|
1187
1335
|
expose :digest { |status, options| Digest::MD5.hexdigest(status.txt) }
|
1188
1336
|
expose :replies, using: API::Status, as: :replies
|
1189
1337
|
end
|
@@ -1211,9 +1359,10 @@ module API
|
|
1211
1359
|
class Statuses < Grape::API
|
1212
1360
|
version 'v1'
|
1213
1361
|
|
1214
|
-
desc 'Create a status'
|
1362
|
+
desc 'Create a status'
|
1363
|
+
params do
|
1215
1364
|
requires :all, except: [:ip], using: API::Entities::Status.documentation.except(:id)
|
1216
|
-
|
1365
|
+
end
|
1217
1366
|
post '/status' do
|
1218
1367
|
Status.create! params
|
1219
1368
|
end
|
@@ -1450,7 +1599,7 @@ default anchors requests to match from the start to the end, or not at all.
|
|
1450
1599
|
Rails solves this problem by using a `anchor: false` option in your routes.
|
1451
1600
|
In Grape this option can be used as well when a method is defined.
|
1452
1601
|
|
1453
|
-
For instance when
|
1602
|
+
For instance when your API needs to get part of an URL, for instance:
|
1454
1603
|
|
1455
1604
|
```ruby
|
1456
1605
|
class TwitterAPI < Grape::API
|
@@ -1540,6 +1689,31 @@ RSpec.configure do |config|
|
|
1540
1689
|
end
|
1541
1690
|
```
|
1542
1691
|
|
1692
|
+
### Stubbing Helpers
|
1693
|
+
|
1694
|
+
Because helpers are mixed in based on the context when an endpoint is defined, it can
|
1695
|
+
be difficult to stub or mock them for testing. The `Grape::Endpoint.before_each` method
|
1696
|
+
can help by allowing you to define behavior on the endpoint that will run before every
|
1697
|
+
request.
|
1698
|
+
|
1699
|
+
```ruby
|
1700
|
+
describe 'an endpoint that needs helpers stubbed' do
|
1701
|
+
before do
|
1702
|
+
Grape::Endpoint.before_each do |endpoint|
|
1703
|
+
endpoint.stub(:helper_name).and_return('desired_value')
|
1704
|
+
end
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
after do
|
1708
|
+
Grape::Endpoint.before_each nil
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
it 'should properly stub the helper' do
|
1712
|
+
# ...
|
1713
|
+
end
|
1714
|
+
end
|
1715
|
+
```
|
1716
|
+
|
1543
1717
|
## Reloading API Changes in Development
|
1544
1718
|
|
1545
1719
|
### Rails 3.x
|
@@ -1583,6 +1757,13 @@ features and discuss issues.
|
|
1583
1757
|
|
1584
1758
|
See [CONTRIBUTING](CONTRIBUTING.md).
|
1585
1759
|
|
1760
|
+
## Hacking on Grape
|
1761
|
+
|
1762
|
+
You can start hacking on Grape on
|
1763
|
+
[Nitrous.IO](https://www.nitrous.io/?utm_source=github.com&utm_campaign=grape&utm_medium=hackonnitrous) in a matter of seconds:
|
1764
|
+
|
1765
|
+
[![Hack intridea/grape on Nitrous.IO](https://d3o0mnbgv6k92a.cloudfront.net/assets/hack-l-v1-3cc067e71372f6045e1949af9d96095b.png)](https://www.nitrous.io/hack_button?source=embed&runtime=rails&repo=intridea%2Fgrape&file_to_open=README.md)
|
1766
|
+
|
1586
1767
|
## License
|
1587
1768
|
|
1588
1769
|
MIT License. See LICENSE for details.
|