grpc-rest 0.1.21 → 0.1.24
Sign up to get free protection for your applications and to get access to all the features.
- 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
|