twirp 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -6
- data/lib/twirp/client.rb +7 -4
- data/lib/twirp/client_json.rb +2 -2
- data/lib/twirp/client_resp.rb +3 -1
- data/lib/twirp/service.rb +1 -1
- data/lib/twirp/version.rb +1 -1
- data/test/client_json_test.rb +3 -0
- data/test/client_test.rb +8 -0
- data/test/fake_services.rb +5 -16
- data/twirp.gemspec +4 -3
- metadata +34 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84ca98464f629eded22f43e5f6be8d5f720287e32056db5535ec71d529745504
|
4
|
+
data.tar.gz: 7f52befd48f263ec529820cdc0a376becee5bff8d83b206d443df288125cf65d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1199fe21d97365b929b03e1f2ae347544c13ba69473638c69c7a5f6097bc4de230c41422f1f019700f3b0a8e7a6475cbc24801cee45c755710031a635b4cc359
|
7
|
+
data.tar.gz: fdf6e077944198c4ae9158080f4120c7039a5b2e5bcfd83535a1e2da103638ccf3f2feab429ad22a3fb33c0ed69c504c8b74979a998bd8491d786273f8542733
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Twirp-Ruby
|
2
2
|
|
3
|
-
[](https://github.com/arthurnn/twirp-ruby/actions/workflows/tests.yml)
|
4
4
|
|
5
|
-
[Twirp is a protocol](https://
|
5
|
+
[Twirp is a protocol](https://twitchtv.github.io/twirp/docs/spec_v5.html) for routing and serialization of services defined in a [.proto file](https://developers.google.com/protocol-buffers/docs/proto3), allowing easy implementation of RPC services with auto-generated clients in different languages.
|
6
6
|
|
7
7
|
The [canonical implementation](https://github.com/twitchtv/twirp) is in Golang. The Twirp-Ruby project is the official implementation in Ruby for both server and clients.
|
8
8
|
|
@@ -11,13 +11,15 @@ The [canonical implementation](https://github.com/twitchtv/twirp) is in Golang.
|
|
11
11
|
|
12
12
|
Add `gem "twirp"` to your Gemfile, or install with `gem install twirp`.
|
13
13
|
|
14
|
-
To auto-generate Ruby code from a proto file, use the `protoc` plugin and the `--ruby_out` option ([see Wiki page](https://github.com/
|
14
|
+
To auto-generate Ruby code from a proto file, use the `protoc` plugin and the `--ruby_out` option ([see Wiki page](https://github.com/arthurnn/twirp-ruby/wiki/Code-Generation)).
|
15
15
|
|
16
|
+
### No backwards compatible breaking changes, between minor versions(1.10.0)
|
16
17
|
|
17
|
-
|
18
|
+
When upgrading from version 1.9.0 to 1.10.0, note that there is a breaking change in the `Twirp::ClientResp#initialize` method. The method now accepts keyword arguments. For more details, refer to this [comparison](https://github.com/arthurnn/twirp-ruby/compare/v1.9.0...v1.10.0#diff-b3c497150f4ae769df1a5d90e43142983cfd4d780392cbaa218d74912fa3a174) and this [issue](https://github.com/arthurnn/twirp-ruby/issues/99).
|
18
19
|
|
19
|
-
|
20
|
+
## Documentation
|
20
21
|
|
22
|
+
[On the wiki](https://github.com/arthurnn/twirp-ruby/wiki).
|
21
23
|
|
22
24
|
## Contributing
|
23
25
|
|
@@ -25,4 +27,4 @@ To auto-generate Ruby code from a proto file, use the `protoc` plugin and the `-
|
|
25
27
|
|
26
28
|
## Releases and changes
|
27
29
|
|
28
|
-
See the [releases](https://github.com/
|
30
|
+
See the [releases](https://github.com/arthurnn/twirp-ruby/releases) page for latest information about released versions.
|
data/lib/twirp/client.rb
CHANGED
@@ -178,7 +178,7 @@ module Twirp
|
|
178
178
|
# natively with twirp-ruby. For normal Faraday, this is a noop.
|
179
179
|
def rpc_response_thennable(resp)
|
180
180
|
return yield resp unless resp.respond_to?(:then)
|
181
|
-
|
181
|
+
|
182
182
|
resp.then do |resp|
|
183
183
|
yield resp
|
184
184
|
end
|
@@ -186,15 +186,18 @@ module Twirp
|
|
186
186
|
|
187
187
|
def rpc_response_to_clientresp(resp, content_type, rpcdef)
|
188
188
|
if resp.status != 200
|
189
|
-
return ClientResp.new(error: self.class.error_from_response(resp))
|
189
|
+
return ClientResp.new(error: self.class.error_from_response(resp), headers: resp.headers)
|
190
190
|
end
|
191
191
|
|
192
192
|
if resp.headers['Content-Type'] != content_type
|
193
|
-
return ClientResp.new(
|
193
|
+
return ClientResp.new(
|
194
|
+
error: Twirp::Error.internal("Expected response Content-Type #{content_type.inspect} but found #{resp.headers['Content-Type'].inspect}"),
|
195
|
+
headers: resp.headers
|
196
|
+
)
|
194
197
|
end
|
195
198
|
|
196
199
|
data = Encoding.decode(resp.body, rpcdef[:output_class], content_type)
|
197
|
-
return ClientResp.new(data: data, body: resp.body)
|
200
|
+
return ClientResp.new(data: data, body: resp.body, headers: resp.headers)
|
198
201
|
end
|
199
202
|
|
200
203
|
end
|
data/lib/twirp/client_json.rb
CHANGED
@@ -46,11 +46,11 @@ module Twirp
|
|
46
46
|
|
47
47
|
def rpc_response_to_clientresp(resp)
|
48
48
|
if resp.status != 200
|
49
|
-
return ClientResp.new(error: self.class.error_from_response(resp))
|
49
|
+
return ClientResp.new(error: self.class.error_from_response(resp), headers: resp.headers)
|
50
50
|
end
|
51
51
|
|
52
52
|
data = Encoding.decode_json(resp.body)
|
53
|
-
return ClientResp.new(data: data, body: resp.body)
|
53
|
+
return ClientResp.new(data: data, body: resp.body, headers: resp.headers)
|
54
54
|
end
|
55
55
|
|
56
56
|
end
|
data/lib/twirp/client_resp.rb
CHANGED
@@ -16,11 +16,13 @@ module Twirp
|
|
16
16
|
attr_accessor :data
|
17
17
|
attr_accessor :body
|
18
18
|
attr_accessor :error
|
19
|
+
attr_accessor :headers
|
19
20
|
|
20
|
-
def initialize(data: nil, body: nil, error: nil)
|
21
|
+
def initialize(data: nil, body: nil, error: nil, headers: nil)
|
21
22
|
@data = data
|
22
23
|
@error = error
|
23
24
|
@body = body
|
25
|
+
@headers = headers
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
data/lib/twirp/service.rb
CHANGED
@@ -138,7 +138,7 @@ module Twirp
|
|
138
138
|
input = nil
|
139
139
|
begin
|
140
140
|
body_str = rack_request.body.read
|
141
|
-
rack_request.body.rewind # allow other middleware to read again (https://github.com/
|
141
|
+
rack_request.body.rewind # allow other middleware to read again (https://github.com/arthurnn/twirp-ruby/issues/50)
|
142
142
|
input = Encoding.decode(body_str, env[:input_class], content_type)
|
143
143
|
rescue => e
|
144
144
|
error_msg = "Invalid request body for rpc method #{method_name.inspect} with Content-Type=#{content_type}"
|
data/lib/twirp/version.rb
CHANGED
data/test/client_json_test.rb
CHANGED
@@ -27,6 +27,7 @@ class ClientJSONTest < Minitest::Test
|
|
27
27
|
assert_nil resp.error
|
28
28
|
refute_nil resp.data
|
29
29
|
assert_equal 3, resp.data["blah_resp"]
|
30
|
+
refute_nil resp.headers
|
30
31
|
end
|
31
32
|
|
32
33
|
def test_client_json_thennable
|
@@ -77,6 +78,7 @@ class ClientJSONTest < Minitest::Test
|
|
77
78
|
refute_nil resp.error
|
78
79
|
assert_equal :invalid_argument, resp.error.code
|
79
80
|
assert_equal "dont like empty", resp.error.msg
|
81
|
+
refute_nil resp.headers
|
80
82
|
end
|
81
83
|
|
82
84
|
def test_client_bad_json_route
|
@@ -88,6 +90,7 @@ class ClientJSONTest < Minitest::Test
|
|
88
90
|
assert_nil resp.data
|
89
91
|
refute_nil resp.error
|
90
92
|
assert_equal :bad_route, resp.error.code
|
93
|
+
refute_nil resp.headers
|
91
94
|
end
|
92
95
|
|
93
96
|
|
data/test/client_test.rb
CHANGED
@@ -114,6 +114,7 @@ class ClientTest < Minitest::Test
|
|
114
114
|
resp = c.make_hat(inches: 666)
|
115
115
|
assert_nil resp.error
|
116
116
|
refute_nil resp.data
|
117
|
+
refute_nil resp.headers
|
117
118
|
end
|
118
119
|
|
119
120
|
def test_proto_serialized_request_body
|
@@ -128,6 +129,7 @@ class ClientTest < Minitest::Test
|
|
128
129
|
resp = c.make_hat(Example::Size.new(inches: 666))
|
129
130
|
assert_nil resp.error
|
130
131
|
refute_nil resp.data
|
132
|
+
refute_nil resp.headers
|
131
133
|
end
|
132
134
|
|
133
135
|
def test_proto_twirp_error
|
@@ -139,6 +141,7 @@ class ClientTest < Minitest::Test
|
|
139
141
|
refute_nil resp.error
|
140
142
|
assert_equal :internal, resp.error.code
|
141
143
|
assert_equal "something went wrong", resp.error.msg
|
144
|
+
refute_nil resp.headers
|
142
145
|
end
|
143
146
|
|
144
147
|
def test_proto_intermediary_plain_error
|
@@ -153,6 +156,7 @@ class ClientTest < Minitest::Test
|
|
153
156
|
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
|
154
157
|
assert_equal "Response is not JSON", resp.error.meta[:not_a_twirp_error_because]
|
155
158
|
assert_equal "plain text error from proxy", resp.error.meta[:body]
|
159
|
+
refute_nil resp.headers
|
156
160
|
end
|
157
161
|
|
158
162
|
def test_proto_redirect_error
|
@@ -166,6 +170,7 @@ class ClientTest < Minitest::Test
|
|
166
170
|
assert_equal "Unexpected HTTP Redirect from location=http://rainbow.com", resp.error.msg
|
167
171
|
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
|
168
172
|
assert_equal "Redirects not allowed on Twirp requests", resp.error.meta[:not_a_twirp_error_because]
|
173
|
+
refute_nil resp.headers
|
169
174
|
end
|
170
175
|
|
171
176
|
def test_proto_missing_response_header
|
@@ -176,6 +181,7 @@ class ClientTest < Minitest::Test
|
|
176
181
|
refute_nil resp.error
|
177
182
|
assert_equal :internal, resp.error.code
|
178
183
|
assert_equal 'Expected response Content-Type "application/protobuf" but found nil', resp.error.msg
|
184
|
+
refute_nil resp.headers
|
179
185
|
end
|
180
186
|
|
181
187
|
def test_error_with_invalid_code
|
@@ -187,6 +193,7 @@ class ClientTest < Minitest::Test
|
|
187
193
|
refute_nil resp.error
|
188
194
|
assert_equal :internal, resp.error.code
|
189
195
|
assert_equal "Invalid Twirp error code: unicorn", resp.error.msg
|
196
|
+
refute_nil resp.headers
|
190
197
|
end
|
191
198
|
|
192
199
|
def test_error_with_no_code
|
@@ -201,6 +208,7 @@ class ClientTest < Minitest::Test
|
|
201
208
|
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
|
202
209
|
assert_equal 'Response is JSON but it has no "code" attribute', resp.error.meta[:not_a_twirp_error_because]
|
203
210
|
assert_equal '{"msg":"I have no code of honor"}', resp.error.meta[:body]
|
211
|
+
refute_nil resp.headers
|
204
212
|
end
|
205
213
|
|
206
214
|
# Call .rpc on JSON client
|
data/test/fake_services.rb
CHANGED
@@ -5,17 +5,8 @@ require_relative '../lib/twirp'
|
|
5
5
|
|
6
6
|
# Protobuf messages.
|
7
7
|
# An example of the result of the protoc ruby code generator.
|
8
|
-
|
9
|
-
|
10
|
-
optional :inches, :int32, 1
|
11
|
-
end
|
12
|
-
add_message "example.Hat" do
|
13
|
-
optional :inches, :int32, 1
|
14
|
-
optional :color, :string, 2
|
15
|
-
end
|
16
|
-
add_message "example.Empty" do
|
17
|
-
end
|
18
|
-
end
|
8
|
+
descriptor_data = "\n\ntest.proto\x12\x07\x65xample\"\x16\n\x04Size\x12\x0e\n\x06inches\x18\x01 \x01(\x05\"$\n\x03Hat\x12\x0e\n\x06inches\x18\x01 \x01(\x05\x12\r\n\x05\x63olor\x18\x02 \x01(\t\"\x07\n\x05\x45mptyb\x06proto3"
|
9
|
+
Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data)
|
19
10
|
|
20
11
|
module Example
|
21
12
|
Size = Google::Protobuf::DescriptorPool.generated_pool.lookup("example.Size").msgclass
|
@@ -56,11 +47,9 @@ class EmptyClient < Twirp::Client
|
|
56
47
|
end
|
57
48
|
|
58
49
|
# Foo message
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
50
|
+
descriptor_data = "\n\tfoo.proto\"\x12\n\x03\x46oo\x12\x0b\n\x03\x66oo\x18\x01 \x01(\tb\x06proto3"
|
51
|
+
Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data)
|
52
|
+
|
64
53
|
Foo = Google::Protobuf::DescriptorPool.generated_pool.lookup("Foo").msgclass
|
65
54
|
|
66
55
|
# Foo Client
|
data/twirp.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ["forbescyrus@gmail.com", "tothemario@gmail.com"]
|
12
12
|
spec.summary = %q{Twirp services in Ruby.}
|
13
13
|
spec.description = %q{Twirp is a simple RPC framework with protobuf service definitions. The Twirp gem provides native support for Ruby.}
|
14
|
-
spec.homepage = "https://github.com/
|
14
|
+
spec.homepage = "https://github.com/arthurnn/twirp-ruby"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = Dir['lib/**/*'] + %w(Gemfile LICENSE README.md twirp.gemspec)
|
@@ -19,11 +19,12 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.required_ruby_version = '>= 1.9'
|
22
|
-
spec.add_runtime_dependency 'google-protobuf', '
|
22
|
+
spec.add_runtime_dependency 'google-protobuf', '>= 3.25', '< 5.a'
|
23
23
|
spec.add_runtime_dependency 'faraday', '< 3' # for clients
|
24
|
+
spec.add_dependency 'rack', '>= 2.2.3', '< 3' # see https://github.com/arthurnn/twirp-ruby/issues/111
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler', '~> 2'
|
26
27
|
spec.add_development_dependency 'minitest', '>= 5'
|
27
28
|
spec.add_development_dependency 'rake'
|
28
|
-
|
29
|
+
|
29
30
|
end
|
metadata
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twirp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyrus A. Forbes
|
8
8
|
- Mario Izquierdo
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-protobuf
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '3.0'
|
21
18
|
- - ">="
|
22
19
|
- !ruby/object:Gem::Version
|
23
|
-
version: 3.
|
20
|
+
version: '3.25'
|
21
|
+
- - "<"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 5.a
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - "~>"
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: '3.0'
|
31
28
|
- - ">="
|
32
29
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
30
|
+
version: '3.25'
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.a
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: faraday
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,6 +45,26 @@ dependencies:
|
|
45
45
|
- - "<"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '3'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rack
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.2.3
|
55
|
+
- - "<"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3'
|
58
|
+
type: :runtime
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 2.2.3
|
65
|
+
- - "<"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3'
|
48
68
|
- !ruby/object:Gem::Dependency
|
49
69
|
name: bundler
|
50
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,20 +107,6 @@ dependencies:
|
|
87
107
|
- - ">="
|
88
108
|
- !ruby/object:Gem::Version
|
89
109
|
version: '0'
|
90
|
-
- !ruby/object:Gem::Dependency
|
91
|
-
name: rack
|
92
|
-
requirement: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 2.2.3
|
97
|
-
type: :development
|
98
|
-
prerelease: false
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 2.2.3
|
104
110
|
description: Twirp is a simple RPC framework with protobuf service definitions. The
|
105
111
|
Twirp gem provides native support for Ruby.
|
106
112
|
email:
|
@@ -129,11 +135,11 @@ files:
|
|
129
135
|
- test/license_header_test.rb
|
130
136
|
- test/service_test.rb
|
131
137
|
- twirp.gemspec
|
132
|
-
homepage: https://github.com/
|
138
|
+
homepage: https://github.com/arthurnn/twirp-ruby
|
133
139
|
licenses:
|
134
140
|
- MIT
|
135
141
|
metadata: {}
|
136
|
-
post_install_message:
|
142
|
+
post_install_message:
|
137
143
|
rdoc_options: []
|
138
144
|
require_paths:
|
139
145
|
- lib
|
@@ -149,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
155
|
version: '0'
|
150
156
|
requirements: []
|
151
157
|
rubygems_version: 3.3.3
|
152
|
-
signing_key:
|
158
|
+
signing_key:
|
153
159
|
specification_version: 4
|
154
160
|
summary: Twirp services in Ruby.
|
155
161
|
test_files:
|