Skip to content

Commit 5fe6dbc

Browse files
Use protocol media for response negotiation.
1 parent a541b90 commit 5fe6dbc

3 files changed

Lines changed: 26 additions & 22 deletions

File tree

lib/utopia/controller/responder.rb

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55

66
require_relative "middleware"
77

8+
require "protocol/http/header/accept"
9+
require "protocol/media/map"
10+
require "protocol/media/type"
11+
require "protocol/media/range"
12+
813
module Utopia
914
module Controller
1015
module Handlers
1116
module JSON
12-
APPLICATION_JSON = HTTP::Accept::ContentType.new("application", "json").freeze
13-
14-
def self.split(*arguments)
15-
APPLICATION_JSON.split(*arguments)
16-
end
17+
APPLICATION_JSON = Protocol::Media::Type.new("application", "json").freeze
1718

1819
def self.call(context, request, media_range, object, **options)
1920
if version = media_range.parameters["version"]
@@ -25,11 +26,7 @@ def self.call(context, request, media_range, object, **options)
2526
end
2627

2728
module Passthrough
28-
WILDCARD = HTTP::Accept::MediaTypes::MediaRange.new("*", "*").freeze
29-
30-
def self.split(*arguments)
31-
WILDCARD.split(*arguments)
32-
end
29+
WILDCARD = Protocol::Media::Range.new("*", "*").freeze
3330

3431
def self.call(context, request, media_range, object, **options)
3532
# Do nothing.
@@ -39,10 +36,6 @@ def self.call(context, request, media_range, object, **options)
3936

4037
class Responder
4138
Handler = Struct.new(:content_type, :block) do
42-
def split(*arguments)
43-
self.content_type.split(*arguments)
44-
end
45-
4639
def call(context, request, media_range, *arguments, **options)
4740
context.instance_exec(media_range, *arguments, **options, &self.block)
4841
end
@@ -56,7 +49,7 @@ def with(object, **options)
5649
end
5750

5851
def initialize
59-
@handlers = HTTP::Accept::MediaTypes::Map.new
52+
@handlers = Protocol::Media::Map.new
6053
end
6154

6255
attr :handlers
@@ -68,10 +61,11 @@ def freeze
6861
end
6962

7063
def call(context, request, *arguments, **options)
71-
# Parse the list of browser preferred content types and return ordered by priority:
72-
media_types = HTTP::Accept::MediaTypes.browser_preferred_media_types(
73-
HTTP::Accept::MediaTypes::HTTP_ACCEPT => Array(request.headers["accept"]).join(",")
74-
)
64+
if accept = request.headers["accept"]
65+
media_types = accept.media_ranges.sort
66+
else
67+
media_types = [Handlers::Passthrough::WILDCARD]
68+
end
7569

7670
handler, media_range = @handlers.for(media_types)
7771

@@ -82,19 +76,22 @@ def call(context, request, *arguments, **options)
8276

8377
# Add a converter for the specified content type. Call the block with the response content if the request accepts the specified content_type.
8478
def handle(content_type, &block)
85-
@handlers << Handler.new(content_type, block)
79+
@handlers[content_type] = Handler.new(content_type, block)
80+
return @handlers
8681
end
8782

8883
def respond_to(context, request)
8984
Responds.new(self, context, request)
9085
end
9186

9287
def with_json
93-
@handlers << Handlers::JSON
88+
@handlers[Handlers::JSON::APPLICATION_JSON] = Handlers::JSON
89+
return @handlers
9490
end
9591

9692
def with_passthrough
97-
@handlers << Handlers::Passthrough
93+
@handlers[Handlers::Passthrough::WILDCARD] = Handlers::Passthrough
94+
return @handlers
9895
end
9996

10097
def with(content_type, &block)

test/utopia/controller/respond.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ def mock_request(path, headers = {})
8383
expect(response.read).to be == '{"user_id":10}'
8484
end
8585

86+
it "can register a passthrough handler" do
87+
responder = Utopia::Controller::Responder.new
88+
89+
expect(responder.with_passthrough).to be == responder.handlers
90+
expect(responder.handlers["*/*"]).to be == Utopia::Controller::Handlers::Passthrough
91+
end
8692
end
8793

8894
describe Utopia::Controller do

utopia.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Gem::Specification.new do |spec|
3535
spec.add_dependency "msgpack"
3636
spec.add_dependency "net-smtp"
3737
spec.add_dependency "protocol-http", "~> 0.58"
38+
spec.add_dependency "protocol-media", "~> 0.1"
3839
spec.add_dependency "protocol-url", "~> 0.4"
3940
spec.add_dependency "samovar", "~> 2.1"
4041
spec.add_dependency "traces", "~> 0.10"

0 commit comments

Comments
 (0)