grpc-rest 0.1.21 → 0.1.24
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 +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +16 -1
- data/lib/base_interceptor.rb +45 -0
- data/lib/grpc_rest/version.rb +1 -1
- data/protoc-gen-rails/internal/output.go +11 -9
- data/protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb +2 -1
- data/spec/base_interceptor_spec.rb +30 -0
- data/spec/spec_helper.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4e105820176e2fb387f9ff63ae82a086de8d1b291d372f8e8ba3d38dfc34859
|
4
|
+
data.tar.gz: 1e480bc608d0524821ba06d408681830294ab34c9e36bd330b881f48128f8e33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8118e6cbb88e44bc3577e66c4639f3e5b87ff18515f1c27d9dd5d458caacac52030f39afbd4a108b2009115b7e28ce9c9c7a810419517f700894538febfe3de
|
7
|
+
data.tar.gz: e591ab5d4d0481048f4e61814d1552d83c782f91191fd4f3f1aa430bacfc257aaac2ff3225152767b5acb7e13f1dcc75c42cb86ae93919d6b3cfc483b7bea53d
|
data/CHANGELOG
CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
+
# 0.1.24 - 2024-12-09
|
11
|
+
- Log error backtraces.
|
12
|
+
|
13
|
+
# 0.1.23 - 2024-11-25
|
14
|
+
- Fix: Return a 400 status code when payload is invalid JSON
|
15
|
+
|
16
|
+
# 0.1.22 - 2024-10-31
|
17
|
+
- Fix: calling `fail!` in gruf Interceptors was failing with an unrelated exception.
|
18
|
+
|
10
19
|
# 0.1.21 - 2024-09-12
|
11
20
|
- Feature: Support gruf Interceptors.
|
12
21
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -154,9 +154,24 @@ service MyService {
|
|
154
154
|
|
155
155
|
## Gruf Interceptors
|
156
156
|
|
157
|
-
grpc-rest supports [gruf](https://github.com/bigcommerce/gruf) Interceptors. As long as you're not using a custom interceptor
|
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
158
|
registry, your interceptors will be called normally around the controller.
|
159
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
|
+
```
|
174
|
+
|
160
175
|
## To Do
|
161
176
|
|
162
177
|
* Replace Go implementation with Ruby (+ executable)
|
@@ -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
@@ -63,7 +63,7 @@ class {{.ControllerName}}Controller < ActionController::Base
|
|
63
63
|
rescue_from GRPC::BadStatus do |e|
|
64
64
|
render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
|
65
65
|
end
|
66
|
-
rescue_from Google::Protobuf::TypeError do |e|
|
66
|
+
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
67
67
|
render json: GrpcRest.error_msg(e), status: :bad_request
|
68
68
|
end
|
69
69
|
METHOD_PARAM_MAP = {
|
@@ -102,20 +102,22 @@ func ProcessService(service *descriptorpb.ServiceDescriptorProto, pkg string) (F
|
|
102
102
|
return FileResult{}, routes, err
|
103
103
|
}
|
104
104
|
restOpts, err := ExtractRestOptions(m)
|
105
|
-
if err != nil {
|
105
|
+
if err != nil {
|
106
|
+
return FileResult{}, routes, err
|
107
|
+
}
|
106
108
|
httpMethod, path, err := MethodAndPath(opts.Pattern)
|
107
109
|
pathInfo, err := ParsedPath(path)
|
108
110
|
if err != nil {
|
109
111
|
return FileResult{}, routes, err
|
110
112
|
}
|
111
113
|
controllerMethod := method{
|
112
|
-
Name:
|
113
|
-
RequestType:
|
114
|
-
Path:
|
115
|
-
RestOptions:
|
116
|
-
HttpMethod:
|
117
|
-
Body:
|
118
|
-
PathInfo:
|
114
|
+
Name: strcase.ToSnake(m.GetName()),
|
115
|
+
RequestType: Classify(m.GetInputType()),
|
116
|
+
Path: path,
|
117
|
+
RestOptions: rubyRestOptions(restOpts),
|
118
|
+
HttpMethod: httpMethod,
|
119
|
+
Body: opts.Body,
|
120
|
+
PathInfo: pathInfo,
|
119
121
|
}
|
120
122
|
data.Methods = append(data.Methods, controllerMethod)
|
121
123
|
routes = append(routes, Route{
|
@@ -11,9 +11,10 @@ class MyServiceController < ActionController::Base
|
|
11
11
|
rescue_from GRPC::BadStatus do |e|
|
12
12
|
render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
|
13
13
|
end
|
14
|
-
rescue_from Google::Protobuf::TypeError do |e|
|
14
|
+
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
15
15
|
render json: GrpcRest.error_msg(e), status: :bad_request
|
16
16
|
end
|
17
|
+
|
17
18
|
METHOD_PARAM_MAP = {
|
18
19
|
|
19
20
|
"test" => [
|
@@ -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/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.24
|
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
|
11
|
+
date: 2024-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- Gemfile.lock
|
82
82
|
- README.md
|
83
83
|
- grpc-rest.gemspec
|
84
|
+
- lib/base_interceptor.rb
|
84
85
|
- lib/grpc_rest.rb
|
85
86
|
- lib/grpc_rest/version.rb
|
86
87
|
- protoc-gen-rails/.goreleaser.yml
|
@@ -101,6 +102,7 @@ files:
|
|
101
102
|
- protoc-gen-rails/testdata/no_service/.keep
|
102
103
|
- protoc-gen-rails/testdata/test.proto
|
103
104
|
- protoc-gen-rails/testdata/test_service.proto
|
105
|
+
- spec/base_interceptor_spec.rb
|
104
106
|
- spec/grpc_rest_spec.rb
|
105
107
|
- spec/gruf_spec.rb
|
106
108
|
- spec/protoc-gen-openapiv2/options/annotations_pb.rb
|
@@ -132,6 +134,7 @@ signing_key:
|
|
132
134
|
specification_version: 4
|
133
135
|
summary: Generate Rails controllers and routes from gRPC definitions.
|
134
136
|
test_files:
|
137
|
+
- spec/base_interceptor_spec.rb
|
135
138
|
- spec/grpc_rest_spec.rb
|
136
139
|
- spec/gruf_spec.rb
|
137
140
|
- spec/protoc-gen-openapiv2/options/annotations_pb.rb
|