Skip to content

Commit f2ff6e2

Browse files
committed
Move Utopia::Responder into Utopia::Controller layer.
1 parent 9f73e5a commit f2ff6e2

File tree

4 files changed

+105
-104
lines changed

4 files changed

+105
-104
lines changed

lib/utopia/controller/respond.rb

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Copyright, 2016-2025, by Samuel Williams.
55

66
require_relative "../http"
7-
require_relative "../responder"
7+
require_relative "responder"
88

99
module Utopia
1010
module Controller
@@ -14,50 +14,6 @@ def self.prepended(base)
1414
base.extend(ClassMethods)
1515
end
1616

17-
module Handlers
18-
module JSON
19-
APPLICATION_JSON = HTTP::Accept::ContentType.new("application", "json").freeze
20-
21-
def self.split(*arguments)
22-
APPLICATION_JSON.split(*arguments)
23-
end
24-
25-
def self.call(context, request, media_range, object, **options)
26-
if version = media_range.parameters["version"]
27-
options[:version] = version.to_s
28-
end
29-
30-
context.succeed! content: object.to_json(options), type: APPLICATION_JSON
31-
end
32-
end
33-
34-
module Passthrough
35-
WILDCARD = HTTP::Accept::MediaTypes::MediaRange.new("*", "*").freeze
36-
37-
def self.split(*arguments)
38-
WILDCARD.split(*arguments)
39-
end
40-
41-
def self.call(context, request, media_range, object, **options)
42-
# Do nothing.
43-
end
44-
end
45-
end
46-
47-
class Responder < Utopia::Responder
48-
def with_json
49-
@handlers << Handlers::JSON
50-
end
51-
52-
def with_passthrough
53-
@handlers << Handlers::Passthrough
54-
end
55-
56-
def with(content_type, &block)
57-
handle(content_type, &block)
58-
end
59-
end
60-
6117
module ClassMethods
6218
def responds
6319
@responder ||= Responder.new

lib/utopia/controller/responder.rb

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2020-2025, by Samuel Williams.
5+
6+
require_relative "middleware"
7+
8+
module Utopia
9+
module Controller
10+
module Handlers
11+
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+
18+
def self.call(context, request, media_range, object, **options)
19+
if version = media_range.parameters["version"]
20+
options[:version] = version.to_s
21+
end
22+
23+
context.succeed! content: object.to_json(options), type: APPLICATION_JSON
24+
end
25+
end
26+
27+
module Passthrough
28+
WILDCARD = HTTP::Accept::MediaTypes::MediaRange.new("*", "*").freeze
29+
30+
def self.split(*arguments)
31+
WILDCARD.split(*arguments)
32+
end
33+
34+
def self.call(context, request, media_range, object, **options)
35+
# Do nothing.
36+
end
37+
end
38+
end
39+
40+
class Responder
41+
Handler = Struct.new(:content_type, :block) do
42+
def split(*arguments)
43+
self.content_type.split(*arguments)
44+
end
45+
46+
def call(context, request, media_range, *arguments, **options)
47+
context.instance_exec(media_range, *arguments, **options, &self.block)
48+
end
49+
end
50+
51+
Responds = Struct.new(:responder, :context, :request) do
52+
# @todo Refactor `object` -> `*arguments`...
53+
def with(object, **options)
54+
responder.call(context, request, object, **options)
55+
end
56+
end
57+
58+
def initialize
59+
@handlers = HTTP::Accept::MediaTypes::Map.new
60+
end
61+
62+
attr :handlers
63+
64+
def freeze
65+
@handlers.freeze
66+
67+
super
68+
end
69+
70+
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(request.env)
73+
74+
handler, media_range = @handlers.for(media_types)
75+
76+
if handler
77+
handler.call(context, request, media_range, *arguments, **options)
78+
end
79+
end
80+
81+
# Add a converter for the specified content type. Call the block with the response content if the request accepts the specified content_type.
82+
def handle(content_type, &block)
83+
@handlers << Handler.new(content_type, block)
84+
end
85+
86+
def respond_to(context, request)
87+
Responds.new(self, context, request)
88+
end
89+
90+
def with_json
91+
@handlers << Handlers::JSON
92+
end
93+
94+
def with_passthrough
95+
@handlers << Handlers::Passthrough
96+
end
97+
98+
def with(content_type, &block)
99+
handle(content_type, &block)
100+
end
101+
end
102+
end
103+
end

lib/utopia/responder.rb

Lines changed: 0 additions & 59 deletions
This file was deleted.

releases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Add agent context.
66
- Better simplification of relative paths, e.g. `../../foo` is not modified to `foo`.
77
- Move top level classes into `class Middleware` in their respective namespaces.
8+
- Move `Utopia::Responder` into `Utopia::Controller` layer.
89

910
## v2.30.1
1011

0 commit comments

Comments
 (0)