Skip to content

Commit

Permalink
feat: Add response type option to endpoints (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattbearman committed May 15, 2024
1 parent aa319b6 commit ee7efe8
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 9 deletions.
2 changes: 2 additions & 0 deletions lib/apia/definitions/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ class Endpoint < Definition
attr_accessor :authenticator
attr_accessor :action
attr_accessor :http_status
attr_accessor :response_type
attr_accessor :paginated_field
attr_reader :fields
attr_reader :scopes

def setup
@fields = FieldSet.new
@http_status = 200
@response_type = Apia::Response::JSON
@scopes = []
end

Expand Down
4 changes: 4 additions & 0 deletions lib/apia/dsls/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ def http_status(status)
@definition.http_status = status
end

def response_type(type)
@definition.response_type = type
end

def field(name, *args, type: nil, **options, &block)
if @definition.fields_overriden?
raise Apia::StandardError, 'Cannot add fields to an endpoint that has a separate fieldset'
Expand Down
4 changes: 2 additions & 2 deletions lib/apia/rack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class << self
# @param headers [Hash]
# @return [Array]
def plain_triplet(body, status: 200, headers: {})
response_triplet(body, content_type: 'text/plain', status: status, headers: headers)
response_triplet(body, content_type: Apia::Response::PLAIN, status: status, headers: headers)
end

# Return a JSON-ready triplet for the given body.
Expand All @@ -169,7 +169,7 @@ def plain_triplet(body, status: 200, headers: {})
# @param headers [Hash]
# @return [Array]
def json_triplet(body, status: 200, headers: {})
response_triplet(body.to_json, content_type: 'application/json', status: status, headers: headers)
response_triplet(body.to_json, content_type: Apia::Response::JSON, status: status, headers: headers)
end

# Return a triplet for the given body.
Expand Down
13 changes: 6 additions & 7 deletions lib/apia/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ module Apia
class Response

TYPES = [
JSON = :json,
PLAIN = :plain
JSON = 'application/json',
PLAIN = 'text/plain'
].freeze

attr_accessor :status
Expand All @@ -21,11 +21,14 @@ def initialize(request, endpoint)
@endpoint = endpoint

@status = @endpoint.definition.http_status_code
@type = @endpoint.definition.response_type
@fields = {}
@headers = {}
end

def plain_text_body(body)
warn '[DEPRECATION] `plain_text_body` is deprecated. Please set use `response_type` in the endpoint definition, and set the response `body` directly instead.'

@type = PLAIN
@body = body
end
Expand Down Expand Up @@ -63,15 +66,11 @@ def body
@body || hash
end

def type
@type || JSON
end

# Return the rack triplet for this response
#
# @return [Array]
def rack_triplet
case type
case @type
when JSON
Rack.json_triplet(body, headers: headers, status: status)
when PLAIN
Expand Down
60 changes: 60 additions & 0 deletions spec/specs/apia/response_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,59 @@
end

context 'with a plain text response' do
before { endpoint.response_type Apia::Response::PLAIN }

let(:endpoint) { Apia::Endpoint.create('ExampleEndpoint') }

it 'should return 200 by default' do
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
expect(response.rack_triplet[0]).to eq 200
end

it 'should return whatever the status is set to' do
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
response.status = 403
expect(response.rack_triplet[0]).to eq 403
end

it 'should return the status from the endpoint' do
endpoint.http_status :created
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
expect(response.rack_triplet[0]).to eq 201
end

it 'should return the headers' do
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
response.add_header 'x-example', 'hi!'
expect(response.rack_triplet[1]['x-example']).to eq 'hi!'
end

it 'should always provide the content-type as plain' do
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
expect(response.rack_triplet[1]['content-type']).to eq 'text/plain'
end

it 'should always set a content-length' do
response = Apia::Response.new(request, endpoint)
response.body = ''
expect(response.rack_triplet[2][0]).to eq ''
expect(response.rack_triplet[1]['content-length']).to eq '0'
end

it 'should return the body if one has been set' do
response = Apia::Response.new(request, endpoint)
response.body = 'hello world'
expect(response.rack_triplet[2][0]).to eq 'hello world'
expect(response.rack_triplet[1]['content-length']).to eq '11'
end
end

context 'with a legacy plain text response' do
it 'should return 200 by default' do
endpoint = Apia::Endpoint.create('ExampleEndpoint')
response = Apia::Response.new(request, endpoint)
Expand Down Expand Up @@ -138,6 +191,13 @@
expect(response.rack_triplet[2][0]).to eq 'hello world'
expect(response.rack_triplet[1]['content-length']).to eq '11'
end

it 'should warn that the method is deprecated' do
endpoint = Apia::Endpoint.create('ExampleEndpoint')
response = Apia::Response.new(request, endpoint)
expect(response).to receive(:warn).with('[DEPRECATION] `plain_text_body` is deprecated. Please set use `response_type` in the endpoint definition, and set the response `body` directly instead.')
response.plain_text_body('hello world')
end
end
end
end

0 comments on commit ee7efe8

Please sign in to comment.