Skip to content

Commit 88372d3

Browse files
committed
un-deprecate stream-like objects
- this splits the "stream" and "file" inside_route methods - file is purely for specifying a file (and utilizing sendfile when it can) - stream is purely for stream-like objects.. This allows you to have streaming responses of generated data
1 parent b645fb4 commit 88372d3

File tree

9 files changed

+43
-33
lines changed

9 files changed

+43
-33
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Your contribution here.
66
* [#1850](https://github.com/ruby-grape/grape/pull/1850): Adds `same_as` validator - [@glaucocustodio](https://github.com/glaucocustodio).
77
* [#1833](https://github.com/ruby-grape/grape/pull/1833): Allows to set the `ParamBuilder` globally - [@myxoh](https://github.com/myxoh).
8+
* [#1520](https://github.com/ruby-grape/grape/pull/1520): un-deprecate stream-like objects - [@urkle](https://github.com/urkle).
89

910
#### Fixes
1011

lib/grape.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ module Presenters
185185
autoload :Presenter
186186
end
187187

188-
module ServeFile
188+
module ServeStream
189189
extend ::ActiveSupport::Autoload
190-
autoload :FileResponse
191190
autoload :FileBody
192191
autoload :SendfileResponse
192+
autoload :StreamResponse
193193
end
194194
end
195195

lib/grape/dsl/inside_route.rb

+14-5
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,13 @@ def return_no_content
257257
# GET /file # => "contents of file"
258258
def file(value = nil)
259259
if value.is_a?(String)
260-
file_body = Grape::ServeFile::FileBody.new(value)
261-
@file = Grape::ServeFile::FileResponse.new(file_body)
260+
file_body = Grape::ServeStream::FileBody.new(value)
261+
@stream = Grape::ServeStream::SteamResponse.new(file_body)
262262
elsif !value.is_a?(NilClass)
263263
warn '[DEPRECATION] Argument as FileStreamer-like object is deprecated. Use path to file instead.'
264-
@file = Grape::ServeFile::FileResponse.new(value)
264+
@stream = Grape::ServeStream::StreamResponse.new(value)
265265
else
266-
@file
266+
@stream
267267
end
268268
end
269269

@@ -286,7 +286,16 @@ def stream(value = nil)
286286
header 'Content-Length', nil
287287
header 'Transfer-Encoding', nil
288288
header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front)
289-
file(value)
289+
if value.is_a?(String)
290+
warn '[DEPRECATION] Use `file file_path` to stream a file instead.'
291+
file(value)
292+
elsif value.respond_to?(:each)
293+
@stream = Grape::ServeStream::StreamResponse.new(value)
294+
elsif !value.is_a?(NilClass)
295+
raise ArgumentError, 'Stream object must respond to :each.'
296+
else
297+
@stream
298+
end
290299
end
291300

292301
# Allows you to make use of Grape Entities by setting

lib/grape/middleware/formatter.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ def after
3434
def build_formatted_response(status, headers, bodies)
3535
headers = ensure_content_type(headers)
3636

37-
if bodies.is_a?(Grape::ServeFile::FileResponse)
38-
Grape::ServeFile::SendfileResponse.new([], status, headers) do |resp|
39-
resp.body = bodies.file
37+
if bodies.is_a?(Grape::ServeStream::StreamResponse)
38+
Grape::ServeStream::SendfileResponse.new([], status, headers) do |resp|
39+
resp.body = bodies.stream
4040
end
4141
else
4242
# Allow content-type to be explicitly overwritten

lib/grape/serve_file/file_body.rb renamed to lib/grape/serve_stream/file_body.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Grape
2-
module ServeFile
2+
module ServeStream
33
CHUNK_SIZE = 16_384
44

55
# Class helps send file through API

lib/grape/serve_file/sendfile_response.rb renamed to lib/grape/serve_stream/sendfile_response.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Grape
2-
module ServeFile
2+
module ServeStream
33
# Response should respond to to_path method
44
# for using Rack::SendFile middleware
55
class SendfileResponse < Rack::Response

lib/grape/serve_file/file_response.rb renamed to lib/grape/serve_stream/stream_response.rb

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
module Grape
2-
module ServeFile
3-
# A simple class used to identify responses which represent files and do not
2+
module ServeStream
3+
# A simple class used to identify responses which represent streams (or files) and do not
44
# need to be formatted or pre-read by Rack::Response
5-
class FileResponse
6-
attr_reader :file
5+
class StreamResponse
6+
attr_reader :stream
77

8-
# @param file [Object]
9-
def initialize(file)
10-
@file = file
8+
# @param stream [Object]
9+
def initialize(stream)
10+
@stream = stream
1111
end
1212

1313
# Equality provided mostly for tests.
1414
#
1515
# @return [Boolean]
1616
def ==(other)
17-
file == other.file
17+
stream == other.stream
1818
end
1919
end
2020
end

spec/grape/dsl/inside_route_spec.rb

+10-10
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,15 @@ def initialize
206206
let(:file_path) { '/some/file/path' }
207207

208208
let(:file_response) do
209-
file_body = Grape::ServeFile::FileBody.new(file_path)
210-
Grape::ServeFile::FileResponse.new(file_body)
209+
file_body = Grape::ServeStream::FileBody.new(file_path)
210+
Grape::ServeStream::StreamResponse.new(file_body)
211211
end
212212

213213
before do
214214
subject.file file_path
215215
end
216216

217-
it 'returns value wrapped in FileResponse' do
217+
it 'returns value wrapped in StreamResponse' do
218218
expect(subject.file).to eq file_response
219219
end
220220
end
@@ -223,14 +223,14 @@ def initialize
223223
let(:file_object) { Class.new }
224224

225225
let(:file_response) do
226-
Grape::ServeFile::FileResponse.new(file_object)
226+
Grape::ServeStream::StreamResponse.new(file_object)
227227
end
228228

229229
before do
230230
subject.file file_object
231231
end
232232

233-
it 'returns value wrapped in FileResponse' do
233+
it 'returns value wrapped in StreamResponse' do
234234
expect(subject.file).to eq file_response
235235
end
236236
end
@@ -243,7 +243,7 @@ def initialize
243243

244244
describe '#stream' do
245245
describe 'set' do
246-
let(:file_object) { Class.new }
246+
let(:file_object) { double('StreamerObject', each: nil) }
247247

248248
before do
249249
subject.header 'Cache-Control', 'cache'
@@ -252,12 +252,12 @@ def initialize
252252
subject.stream file_object
253253
end
254254

255-
it 'returns value wrapped in FileResponse' do
256-
expect(subject.stream).to eq Grape::ServeFile::FileResponse.new(file_object)
255+
it 'returns value wrapped in StreamResponse' do
256+
expect(subject.stream).to eq Grape::ServeStream::StreamResponse.new(file_object)
257257
end
258258

259-
it 'also sets result of file to value wrapped in FileResponse' do
260-
expect(subject.file).to eq Grape::ServeFile::FileResponse.new(file_object)
259+
it 'also sets result of file to value wrapped in StreamResponse' do
260+
expect(subject.file).to eq Grape::ServeStream::StreamResponse.new(file_object)
261261
end
262262

263263
it 'sets Cache-Control header to no-cache' do

spec/grape/middleware/formatter_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,12 @@ def to_xml
371371
end
372372

373373
context 'send file' do
374-
let(:body) { Grape::ServeFile::FileResponse.new('file') }
374+
let(:body) { Grape::ServeStream::StreamResponse.new('file') }
375375
let(:app) { ->(_env) { [200, {}, body] } }
376376

377-
it 'returns Grape::Uril::SendFileReponse' do
377+
it 'returns Grape::ServerStream::SendFileReponse' do
378378
env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' }
379-
expect(subject.call(env)).to be_a(Grape::ServeFile::SendfileResponse)
379+
expect(subject.call(env)).to be_a(Grape::ServeStream::SendfileResponse)
380380
end
381381
end
382382

0 commit comments

Comments
 (0)