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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b19a325cd920ec6632682c8f91b54e06a09444cece910dbc176e898f8e504cb
4
- data.tar.gz: 3fa53b62032088e7e57cae354326188cb93c22312d7dc463111b4d5a6992b68c
3
+ metadata.gz: 47964383a0aa5a5835edd72fae78e2febe1364fdd13f598a588dc3702f5f882b
4
+ data.tar.gz: 14255db74de1d544d8964f3bb3b2e5515f6a25d50ab54bd0e00e6eb550ec9309
5
5
  SHA512:
6
- metadata.gz: 235e5ea946e9e6b10be20485775d0f55f46b0ab1ecb7612f75e98c75be7ff0ca75b438e1649d3abc298196501615425675968cf0605f8968e3771cd8cde897e6
7
- data.tar.gz: 10d3caaa87389dca93982af06ce8143e615d0b6b2133f9485c4d51ec6e18b043faaa836960fcc141954e0fac07b644eba50b256062a22f5fed8c5b5a4f04da4a
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.19)
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
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency('rails', '>= 6.0')
23
23
 
24
24
  spec.add_development_dependency('rspec-rails')
25
+ spec.add_development_dependency('gruf')
25
26
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module GrpcRest
2
- VERSION = '0.1.20'
2
+ VERSION = '0.1.22'
3
3
  end
data/lib/grpc_rest.rb CHANGED
@@ -203,7 +203,18 @@ module GrpcRest
203
203
  active_call: nil,
204
204
  message: request
205
205
  )
206
- handler.send(method.to_sym)
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.20
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-09-10 00:00:00.000000000 Z
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