grpc-rest 0.1.20 → 0.1.22
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/CHANGELOG +6 -0
- data/Gemfile.lock +13 -1
- data/README.md +19 -0
- data/grpc-rest.gemspec +1 -0
- data/lib/base_interceptor.rb +45 -0
- data/lib/grpc_rest/version.rb +1 -1
- data/lib/grpc_rest.rb +12 -1
- data/spec/base_interceptor_spec.rb +30 -0
- data/spec/gruf_spec.rb +51 -0
- data/spec/spec_helper.rb +1 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47964383a0aa5a5835edd72fae78e2febe1364fdd13f598a588dc3702f5f882b
|
4
|
+
data.tar.gz: 14255db74de1d544d8964f3bb3b2e5515f6a25d50ab54bd0e00e6eb550ec9309
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d85e2f3169ec0dedff6f49e193ac1208caeee918c54b99ab3ee18f05973defad99edb8587fab5fe89cdbfb89d44278eda50f329e00e1bb304722ef10ef7c693
|
7
|
+
data.tar.gz: 7ab65c78dc7aadac67a325705d28a3b79873ce24562fa02f1e4f71500536612d49c58806259ed8340b65bd53b3f2f64bf9946b597751d4ff67ae29b086856d63
|
data/CHANGELOG
CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
+
# 0.1.22 - 2024-10-31
|
11
|
+
- Fix: calling `fail!` in gruf Interceptors was failing with an unrelated exception.
|
12
|
+
|
13
|
+
# 0.1.21 - 2024-09-12
|
14
|
+
- Feature: Support gruf Interceptors.
|
15
|
+
|
10
16
|
# 0.1.20 - 2024-09-10
|
11
17
|
- Fix: Repeated float values weren't being treated as arrays and were crashing.
|
12
18
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
grpc-rest (0.1.
|
4
|
+
grpc-rest (0.1.21)
|
5
5
|
grpc
|
6
6
|
rails (>= 6.0)
|
7
7
|
|
@@ -91,8 +91,18 @@ GEM
|
|
91
91
|
grpc (1.62.0-x86_64-linux)
|
92
92
|
google-protobuf (~> 3.25)
|
93
93
|
googleapis-common-protos-types (~> 1.0)
|
94
|
+
grpc-tools (1.64.0)
|
95
|
+
gruf (2.20.0)
|
96
|
+
activesupport (> 4)
|
97
|
+
concurrent-ruby (> 1)
|
98
|
+
grpc (~> 1.10)
|
99
|
+
grpc-tools (~> 1.10)
|
100
|
+
json (>= 2.3)
|
101
|
+
slop (>= 4.6)
|
102
|
+
zeitwerk (>= 2)
|
94
103
|
i18n (1.14.4)
|
95
104
|
concurrent-ruby (~> 1.0)
|
105
|
+
json (2.7.2)
|
96
106
|
loofah (2.22.0)
|
97
107
|
crass (~> 1.0.2)
|
98
108
|
nokogiri (>= 1.12.0)
|
@@ -169,6 +179,7 @@ GEM
|
|
169
179
|
rspec-mocks (~> 3.13)
|
170
180
|
rspec-support (~> 3.13)
|
171
181
|
rspec-support (3.13.1)
|
182
|
+
slop (4.10.1)
|
172
183
|
thor (1.3.1)
|
173
184
|
timeout (0.4.1)
|
174
185
|
tzinfo (2.0.6)
|
@@ -184,6 +195,7 @@ PLATFORMS
|
|
184
195
|
|
185
196
|
DEPENDENCIES
|
186
197
|
grpc-rest!
|
198
|
+
gruf
|
187
199
|
rspec-rails
|
188
200
|
|
189
201
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -152,6 +152,25 @@ service MyService {
|
|
152
152
|
}
|
153
153
|
```
|
154
154
|
|
155
|
+
## Gruf Interceptors
|
156
|
+
|
157
|
+
grpc-rest supports [gruf](https://github.com/bigcommerce/gruf) Interceptors through a custom `GrpcRest::BaseInterceptor` class. As long as you're not using a custom interceptor
|
158
|
+
registry, your interceptors will be called normally around the controller.
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
require 'grpc_rest/base_interceptor'
|
162
|
+
|
163
|
+
module Interceptors
|
164
|
+
# Interceptor for catching errors from controllers
|
165
|
+
class ErrorInterceptor < GrpcRest::BaseInterceptor
|
166
|
+
|
167
|
+
def call
|
168
|
+
# Your code here
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
155
174
|
|
156
175
|
## To Do
|
157
176
|
|
data/grpc-rest.gemspec
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gruf'
|
4
|
+
|
5
|
+
module GrpcRest
|
6
|
+
# Fixes an issue with the fail! method since the active call is not instantiated yet.
|
7
|
+
# Overloads https://github.com/bigcommerce/gruf/blob/main/lib/gruf/errors/helpers.rb#L34
|
8
|
+
class BaseInterceptor < ::Gruf::Interceptors::ServerInterceptor
|
9
|
+
def fail!(error_code, _app_code, message = 'unknown error', metadata = {})
|
10
|
+
raise grpc_error(error_code, message.to_s, metadata)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Ported from https://github.com/flipp-oss/grpc-rest/blob/main/lib/grpc_rest.rb#L142
|
16
|
+
def grpc_error(error_code, message, metadata)
|
17
|
+
case error_code
|
18
|
+
when :ok
|
19
|
+
GRPC::Ok.new(message, metadata)
|
20
|
+
when 499
|
21
|
+
GRPC::Cancelled.new(message, metadata)
|
22
|
+
when :bad_request, :invalid_argument
|
23
|
+
GRPC::InvalidArgument.new(message, metadata)
|
24
|
+
when :gateway_timeout
|
25
|
+
GRPC::DeadlineExceeded.new(message, metadata)
|
26
|
+
when :not_found
|
27
|
+
GRPC::NotFound.new(message, metadata)
|
28
|
+
when :conflict
|
29
|
+
GRPC::AlreadyExists.new(message, metadata)
|
30
|
+
when :forbidden
|
31
|
+
GRPC::PermissionDenied.new(message, metadata)
|
32
|
+
when :unauthorized
|
33
|
+
GRPC::Unauthenticated.new(message, metadata)
|
34
|
+
when :too_many_requests
|
35
|
+
GRPC::ResourceExhausted.new(message, metadata)
|
36
|
+
when :not_implemented
|
37
|
+
GRPC::Unimplemented.new(message, metadata)
|
38
|
+
when :service_unavailable
|
39
|
+
GRPC::Unavailable.new(message, metadata)
|
40
|
+
else
|
41
|
+
GRPC::Internal.new(message, metadata)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/grpc_rest/version.rb
CHANGED
data/lib/grpc_rest.rb
CHANGED
@@ -203,7 +203,18 @@ module GrpcRest
|
|
203
203
|
active_call: nil,
|
204
204
|
message: request
|
205
205
|
)
|
206
|
-
|
206
|
+
Gruf::Interceptors::Context.new(gruf_interceptors(request)).intercept! do
|
207
|
+
handler.send(method.to_sym)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# @param request [Google::Protobuf::AbstractMessage]
|
212
|
+
# @return [Array<Gruf::Interceptors::Base>]
|
213
|
+
def gruf_interceptors(request)
|
214
|
+
error = Gruf::Error.new
|
215
|
+
interceptors = Gruf.interceptors.prepare(request, error)
|
216
|
+
interceptors.delete_if { |k| k.class.name.split('::').first == 'Gruf' }
|
217
|
+
interceptors
|
207
218
|
end
|
208
219
|
|
209
220
|
def send_grpc_request(service, method, request)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './spec_helper'
|
4
|
+
require 'src/proto/grpc/testing/test_services_pb'
|
5
|
+
|
6
|
+
RSpec.describe GrpcRest::BaseInterceptor, type: :class do
|
7
|
+
let(:rpc_service) { Grpc::Testing::TestService::Service.new }
|
8
|
+
let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first}
|
9
|
+
let(:message) { Grpc::Testing::SimpleRequest.new }
|
10
|
+
|
11
|
+
describe '#fail!' do
|
12
|
+
let(:error_message) { 'some message' }
|
13
|
+
let(:error_code) { :invalid_argument }
|
14
|
+
|
15
|
+
it 'intercepts and raises the error' do
|
16
|
+
request = Gruf::Controllers::Request.new(
|
17
|
+
method_key: :UnaryCall,
|
18
|
+
service: rpc_service,
|
19
|
+
rpc_desc: rpc_desc,
|
20
|
+
active_call: nil,
|
21
|
+
message: message)
|
22
|
+
interceptor = GrpcRest::BaseInterceptor.new(request, Gruf::Error.new)
|
23
|
+
|
24
|
+
expect{ interceptor.fail!(error_code, error_code, error_message) }.to raise_error(GRPC::InvalidArgument) do |error|
|
25
|
+
expect(error.message).to match(error_message)
|
26
|
+
expect(error.code).to eq(GRPC::Core::StatusCodes::INVALID_ARGUMENT)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/gruf_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative './spec_helper'
|
2
|
+
require_relative './test_service_services_pb'
|
3
|
+
require 'gruf'
|
4
|
+
|
5
|
+
class GrufServerImpl < Gruf::Controllers::Base
|
6
|
+
|
7
|
+
bind ::Testdata::MyService::Service
|
8
|
+
|
9
|
+
def test
|
10
|
+
Testdata::TestResponse.new(some_int: 1, full_response: request.message.to_json)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_2
|
14
|
+
Testdata::TestResponse.new(some_int: 2, full_response: request.message.to_json)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_3
|
18
|
+
Testdata::TestResponse.new(some_int: 3, full_response: request.message.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_4
|
22
|
+
Testdata::TestResponse.new(some_int: 4, full_response: request.message.to_json)
|
23
|
+
end
|
24
|
+
|
25
|
+
cattr_accessor :intercepted
|
26
|
+
end
|
27
|
+
|
28
|
+
class TestInterceptor < ::Gruf::Interceptors::ServerInterceptor
|
29
|
+
def call
|
30
|
+
GrufServerImpl.intercepted = true
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Gruf::Server.new.add_interceptor(TestInterceptor, option_foo: 'value 123')
|
36
|
+
|
37
|
+
RSpec.describe MyServiceController, type: :request do
|
38
|
+
describe 'using get' do
|
39
|
+
it 'should be successful and call interceptors' do
|
40
|
+
GrufServerImpl.intercepted = false
|
41
|
+
get "/test/blah/xyz?test_id=abc"
|
42
|
+
expect(response).to be_successful
|
43
|
+
expect(response.parsed_body).to eq({
|
44
|
+
'someInt' => 1,
|
45
|
+
'fullResponse' => %({"testId":"abc","foobar":"xyz"}),
|
46
|
+
"ignoredKey" => ''
|
47
|
+
})
|
48
|
+
expect(GrufServerImpl.intercepted).to eq(true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -17,6 +17,7 @@ loader.inflector.inflect('protoc-gen-openapiv2' => 'ProtocGenOpenapiv2')
|
|
17
17
|
loader.ignore("#{Rails.root}/spec/test_service_pb.rb")
|
18
18
|
loader.setup
|
19
19
|
require "#{Rails.root}/spec/test_service_pb.rb"
|
20
|
+
require "#{Rails.root}/lib/base_interceptor.rb"
|
20
21
|
|
21
22
|
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
22
23
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc-rest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: gruf
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- daniel.orner@flipp.com
|
@@ -67,6 +81,7 @@ files:
|
|
67
81
|
- Gemfile.lock
|
68
82
|
- README.md
|
69
83
|
- grpc-rest.gemspec
|
84
|
+
- lib/base_interceptor.rb
|
70
85
|
- lib/grpc_rest.rb
|
71
86
|
- lib/grpc_rest/version.rb
|
72
87
|
- protoc-gen-rails/.goreleaser.yml
|
@@ -87,7 +102,9 @@ files:
|
|
87
102
|
- protoc-gen-rails/testdata/no_service/.keep
|
88
103
|
- protoc-gen-rails/testdata/test.proto
|
89
104
|
- protoc-gen-rails/testdata/test_service.proto
|
105
|
+
- spec/base_interceptor_spec.rb
|
90
106
|
- spec/grpc_rest_spec.rb
|
107
|
+
- spec/gruf_spec.rb
|
91
108
|
- spec/protoc-gen-openapiv2/options/annotations_pb.rb
|
92
109
|
- spec/protoc-gen-openapiv2/options/openapiv2_pb.rb
|
93
110
|
- spec/spec_helper.rb
|
@@ -117,7 +134,9 @@ signing_key:
|
|
117
134
|
specification_version: 4
|
118
135
|
summary: Generate Rails controllers and routes from gRPC definitions.
|
119
136
|
test_files:
|
137
|
+
- spec/base_interceptor_spec.rb
|
120
138
|
- spec/grpc_rest_spec.rb
|
139
|
+
- spec/gruf_spec.rb
|
121
140
|
- spec/protoc-gen-openapiv2/options/annotations_pb.rb
|
122
141
|
- spec/protoc-gen-openapiv2/options/openapiv2_pb.rb
|
123
142
|
- spec/spec_helper.rb
|