Skip to content

Commit 58bfd61

Browse files
committed
Merge pull request #1268 from arempe93/document-callbacks
Adds documentation and specs for callback response behaviors
2 parents 86e3cd1 + bff2862 commit 58bfd61

2 files changed

Lines changed: 87 additions & 4 deletions

File tree

README.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,15 +2453,19 @@ Before and after callbacks execute in the following order:
24532453

24542454
Steps 4, 5 and 6 only happen if validation succeeds.
24552455

2456-
E.g. using `before`:
2456+
#### Examples
2457+
2458+
Using a simple `before` block to set a header
24572459

24582460
```ruby
24592461
before do
24602462
header 'X-Robots-Tag', 'noindex'
24612463
end
24622464
```
24632465

2464-
The block applies to every API call within and below the current namespace:
2466+
**Namespaces**
2467+
2468+
Callbacks apply to each API call within and below the current namespace:
24652469

24662470
```ruby
24672471
class MyAPI < Grape::API
@@ -2495,8 +2499,7 @@ GET /foo # 'root - foo - blah'
24952499
GET /foo/bar # 'root - foo - bar - blah'
24962500
```
24972501

2498-
Params on a `namespace` (or whatever alias you are using) also work when using
2499-
`before_validation` or `after_validation`:
2502+
Params on a `namespace` (or whichever alias you are using) will also be available when using `before_validation` or `after_validation`:
25002503

25012504
```ruby
25022505
class MyAPI < Grape::API
@@ -2523,6 +2526,8 @@ GET /123 # 'Fixnum'
25232526
GET /foo # 400 error - 'blah is invalid'
25242527
```
25252528

2529+
**Versioning**
2530+
25262531
When a callback is defined within a version block, it's only called for the routes defined in that block.
25272532

25282533
```ruby
@@ -2556,6 +2561,33 @@ GET /foo/v1 # 'v1-hello'
25562561
GET /foo/v2 # 'v2-hello'
25572562
```
25582563

2564+
**Altering Responses**
2565+
2566+
Using `present` in any callback allows you to add data to a response:
2567+
2568+
```ruby
2569+
class MyAPI < Grape::API
2570+
format :json
2571+
2572+
after_validation do
2573+
present :name, params[:name] if params[:name]
2574+
end
2575+
2576+
get '/greeting' do
2577+
present :greeting, 'Hello!'
2578+
end
2579+
end
2580+
```
2581+
2582+
The behaviour is then:
2583+
2584+
```bash
2585+
GET /greeting # {"greeting":"Hello!"}
2586+
GET /greeting?name=Alan # {"name":"Alan","greeting":"Hello!"}
2587+
```
2588+
2589+
Instead of altering a response, you can also terminate and rewrite it from any callback using `error!`, including `after`. This will cause all subsequent steps in the process to not be called. **This includes the actual api call and any callbacks**
2590+
25592591
## Anchoring
25602592

25612593
Grape by default anchors all request paths, which means that the request URL

spec/grape/endpoint_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,57 @@ def memoized
887887
expect(last_response.body).to eq('body')
888888
end
889889
end
890+
891+
it 'allows adding to response with present' do
892+
subject.format :json
893+
subject.before { present :before, 'before' }
894+
subject.before_validation { present :before_validation, 'before_validation' }
895+
subject.after_validation { present :after_validation, 'after_validation' }
896+
subject.after { present :after, 'after' }
897+
subject.get :all_filters do
898+
present :endpoint, 'endpoint'
899+
end
900+
901+
get '/all_filters'
902+
json = JSON.parse(last_response.body)
903+
expect(json.keys).to match_array %w(before before_validation after_validation endpoint after)
904+
end
905+
906+
context 'when terminating the response with error!' do
907+
it 'breaks normal call chain' do
908+
called = []
909+
subject.before { called << 'before' }
910+
subject.before_validation { called << 'before_validation' }
911+
subject.after_validation { error! :oops, 500 }
912+
subject.after { called << 'after' }
913+
subject.get :error_filters do
914+
called << 'endpoint'
915+
''
916+
end
917+
918+
get '/error_filters'
919+
expect(last_response.status).to eql 500
920+
expect(called).to match_array %w(before before_validation)
921+
end
922+
923+
it 'allows prior and parent filters of same type to run' do
924+
called = []
925+
subject.before { called << 'parent' }
926+
subject.namespace :parent do
927+
before { called << 'prior' }
928+
before { error! :oops, 500 }
929+
before { called << 'subsequent' }
930+
get :hello do
931+
called << :endpoint
932+
'Hello!'
933+
end
934+
end
935+
936+
get '/parent/hello'
937+
expect(last_response.status).to eql 500
938+
expect(called).to match_array %w(parent prior)
939+
end
940+
end
890941
end
891942

892943
context 'anchoring' do

0 commit comments

Comments
 (0)