grpc-rest 0.1.5 → 0.1.7
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/.github/workflows/CI.yml +16 -2
- data/.gitignore +2 -0
- data/CHANGELOG +8 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +190 -0
- data/README.md +10 -26
- data/grpc-rest.gemspec +2 -0
- data/lib/grpc_rest/version.rb +1 -1
- data/lib/grpc_rest.rb +26 -21
- data/protoc-gen-rails/internal/output.go +7 -2
- data/protoc-gen-rails/internal/utils.go +1 -1
- data/protoc-gen-rails/main.go +6 -4
- data/protoc-gen-rails/main_test.go +22 -1
- data/protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb +14 -3
- data/protoc-gen-rails/testdata/base/config/routes/grpc.rb +7 -3
- data/protoc-gen-rails/testdata/no_service/.keep +0 -0
- data/protoc-gen-rails/testdata/test.proto +6 -0
- data/protoc-gen-rails/testdata/test_service.proto +14 -2
- data/spec/grpc_rest_spec.rb +117 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/test_service_pb.rb +44 -0
- data/spec/test_service_services_pb.rb +25 -0
- metadata +29 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8851853946d82493dd832a39be201f3b5b0bc5e70c7837e9be7a3db4d1d30460
|
|
4
|
+
data.tar.gz: a44a3d29c174df98af07cc91693127fbfc8e6a5c42b282bb7119573af53e5d28
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfa0ed32f96706a4d8e6b0bfccc72d2e0d018f64fa4e5e87372bc3527c7b7521d8b1aecc48520df695dda54ac717cc5d7440319ea767c075204464d1965c668c
|
|
7
|
+
data.tar.gz: bbaa98db8d37ec4b91325438422fa1681fc0a35186f3c3e427cd1cb933bceaba7f806fe9cbf4269f4bdbd7315bbe1870b28aae14f4c1d59294dc974333652c4c
|
data/.github/workflows/CI.yml
CHANGED
|
@@ -8,7 +8,7 @@ on:
|
|
|
8
8
|
workflow_dispatch:
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
|
-
test:
|
|
11
|
+
test-go:
|
|
12
12
|
runs-on: [ubuntu-latest]
|
|
13
13
|
steps:
|
|
14
14
|
- name: Checkout code
|
|
@@ -25,8 +25,22 @@ jobs:
|
|
|
25
25
|
- run: git clean -f -d
|
|
26
26
|
- run: cd protoc-gen-rails && go test ./...
|
|
27
27
|
|
|
28
|
+
test-ruby:
|
|
29
|
+
runs-on: [ubuntu-latest]
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout code
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 0
|
|
35
|
+
- name: Setup Ruby
|
|
36
|
+
uses: ruby/setup-ruby@v1
|
|
37
|
+
with:
|
|
38
|
+
ruby-version: '3.3'
|
|
39
|
+
bundler-cache: true
|
|
40
|
+
- run: bundle exec rspec
|
|
41
|
+
|
|
28
42
|
build_and_deploy:
|
|
29
|
-
needs: test
|
|
43
|
+
needs: [test-go, test-ruby]
|
|
30
44
|
runs-on: [ubuntu-latest]
|
|
31
45
|
steps:
|
|
32
46
|
- name: Checkout code
|
data/CHANGELOG
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## UNRELEASED
|
|
9
9
|
|
|
10
|
+
# 0.1.7 - 2024-04-09
|
|
11
|
+
- Added tests.
|
|
12
|
+
- Fixed some bugs around path globbing.
|
|
13
|
+
|
|
14
|
+
# 0.1.6 - 2024-04-05
|
|
15
|
+
- Fixed bug where a blank routes file would be emitted when no services were found.
|
|
16
|
+
- Added a comment line indicating that files are auto-generated.
|
|
17
|
+
|
|
10
18
|
# 0.1.5 - 2024-04-04
|
|
11
19
|
- Parse Google Well Known Types (WKT) in request.
|
|
12
20
|
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
grpc-rest (0.1.6)
|
|
5
|
+
grpc
|
|
6
|
+
rails (>= 6.0)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
actioncable (7.0.8.1)
|
|
12
|
+
actionpack (= 7.0.8.1)
|
|
13
|
+
activesupport (= 7.0.8.1)
|
|
14
|
+
nio4r (~> 2.0)
|
|
15
|
+
websocket-driver (>= 0.6.1)
|
|
16
|
+
actionmailbox (7.0.8.1)
|
|
17
|
+
actionpack (= 7.0.8.1)
|
|
18
|
+
activejob (= 7.0.8.1)
|
|
19
|
+
activerecord (= 7.0.8.1)
|
|
20
|
+
activestorage (= 7.0.8.1)
|
|
21
|
+
activesupport (= 7.0.8.1)
|
|
22
|
+
mail (>= 2.7.1)
|
|
23
|
+
net-imap
|
|
24
|
+
net-pop
|
|
25
|
+
net-smtp
|
|
26
|
+
actionmailer (7.0.8.1)
|
|
27
|
+
actionpack (= 7.0.8.1)
|
|
28
|
+
actionview (= 7.0.8.1)
|
|
29
|
+
activejob (= 7.0.8.1)
|
|
30
|
+
activesupport (= 7.0.8.1)
|
|
31
|
+
mail (~> 2.5, >= 2.5.4)
|
|
32
|
+
net-imap
|
|
33
|
+
net-pop
|
|
34
|
+
net-smtp
|
|
35
|
+
rails-dom-testing (~> 2.0)
|
|
36
|
+
actionpack (7.0.8.1)
|
|
37
|
+
actionview (= 7.0.8.1)
|
|
38
|
+
activesupport (= 7.0.8.1)
|
|
39
|
+
rack (~> 2.0, >= 2.2.4)
|
|
40
|
+
rack-test (>= 0.6.3)
|
|
41
|
+
rails-dom-testing (~> 2.0)
|
|
42
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
43
|
+
actiontext (7.0.8.1)
|
|
44
|
+
actionpack (= 7.0.8.1)
|
|
45
|
+
activerecord (= 7.0.8.1)
|
|
46
|
+
activestorage (= 7.0.8.1)
|
|
47
|
+
activesupport (= 7.0.8.1)
|
|
48
|
+
globalid (>= 0.6.0)
|
|
49
|
+
nokogiri (>= 1.8.5)
|
|
50
|
+
actionview (7.0.8.1)
|
|
51
|
+
activesupport (= 7.0.8.1)
|
|
52
|
+
builder (~> 3.1)
|
|
53
|
+
erubi (~> 1.4)
|
|
54
|
+
rails-dom-testing (~> 2.0)
|
|
55
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
56
|
+
activejob (7.0.8.1)
|
|
57
|
+
activesupport (= 7.0.8.1)
|
|
58
|
+
globalid (>= 0.3.6)
|
|
59
|
+
activemodel (7.0.8.1)
|
|
60
|
+
activesupport (= 7.0.8.1)
|
|
61
|
+
activerecord (7.0.8.1)
|
|
62
|
+
activemodel (= 7.0.8.1)
|
|
63
|
+
activesupport (= 7.0.8.1)
|
|
64
|
+
activestorage (7.0.8.1)
|
|
65
|
+
actionpack (= 7.0.8.1)
|
|
66
|
+
activejob (= 7.0.8.1)
|
|
67
|
+
activerecord (= 7.0.8.1)
|
|
68
|
+
activesupport (= 7.0.8.1)
|
|
69
|
+
marcel (~> 1.0)
|
|
70
|
+
mini_mime (>= 1.1.0)
|
|
71
|
+
activesupport (7.0.8.1)
|
|
72
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
73
|
+
i18n (>= 1.6, < 2)
|
|
74
|
+
minitest (>= 5.1)
|
|
75
|
+
tzinfo (~> 2.0)
|
|
76
|
+
builder (3.2.4)
|
|
77
|
+
concurrent-ruby (1.2.3)
|
|
78
|
+
crass (1.0.6)
|
|
79
|
+
date (3.3.4)
|
|
80
|
+
diff-lcs (1.5.1)
|
|
81
|
+
erubi (1.12.0)
|
|
82
|
+
globalid (1.2.1)
|
|
83
|
+
activesupport (>= 6.1)
|
|
84
|
+
google-protobuf (3.25.3-arm64-darwin)
|
|
85
|
+
google-protobuf (3.25.3-x86_64-linux)
|
|
86
|
+
googleapis-common-protos-types (1.14.0)
|
|
87
|
+
google-protobuf (~> 3.18)
|
|
88
|
+
grpc (1.62.0-arm64-darwin)
|
|
89
|
+
google-protobuf (~> 3.25)
|
|
90
|
+
googleapis-common-protos-types (~> 1.0)
|
|
91
|
+
grpc (1.62.0-x86_64-linux)
|
|
92
|
+
google-protobuf (~> 3.25)
|
|
93
|
+
googleapis-common-protos-types (~> 1.0)
|
|
94
|
+
i18n (1.14.4)
|
|
95
|
+
concurrent-ruby (~> 1.0)
|
|
96
|
+
loofah (2.22.0)
|
|
97
|
+
crass (~> 1.0.2)
|
|
98
|
+
nokogiri (>= 1.12.0)
|
|
99
|
+
mail (2.8.1)
|
|
100
|
+
mini_mime (>= 0.1.1)
|
|
101
|
+
net-imap
|
|
102
|
+
net-pop
|
|
103
|
+
net-smtp
|
|
104
|
+
marcel (1.0.4)
|
|
105
|
+
method_source (1.0.0)
|
|
106
|
+
mini_mime (1.1.5)
|
|
107
|
+
minitest (5.22.3)
|
|
108
|
+
net-imap (0.4.10)
|
|
109
|
+
date
|
|
110
|
+
net-protocol
|
|
111
|
+
net-pop (0.1.2)
|
|
112
|
+
net-protocol
|
|
113
|
+
net-protocol (0.2.2)
|
|
114
|
+
timeout
|
|
115
|
+
net-smtp (0.5.0)
|
|
116
|
+
net-protocol
|
|
117
|
+
nio4r (2.7.1)
|
|
118
|
+
nokogiri (1.16.3-arm64-darwin)
|
|
119
|
+
racc (~> 1.4)
|
|
120
|
+
nokogiri (1.16.3-x86_64-linux)
|
|
121
|
+
racc (~> 1.4)
|
|
122
|
+
racc (1.7.3)
|
|
123
|
+
rack (2.2.9)
|
|
124
|
+
rack-test (2.1.0)
|
|
125
|
+
rack (>= 1.3)
|
|
126
|
+
rails (7.0.8.1)
|
|
127
|
+
actioncable (= 7.0.8.1)
|
|
128
|
+
actionmailbox (= 7.0.8.1)
|
|
129
|
+
actionmailer (= 7.0.8.1)
|
|
130
|
+
actionpack (= 7.0.8.1)
|
|
131
|
+
actiontext (= 7.0.8.1)
|
|
132
|
+
actionview (= 7.0.8.1)
|
|
133
|
+
activejob (= 7.0.8.1)
|
|
134
|
+
activemodel (= 7.0.8.1)
|
|
135
|
+
activerecord (= 7.0.8.1)
|
|
136
|
+
activestorage (= 7.0.8.1)
|
|
137
|
+
activesupport (= 7.0.8.1)
|
|
138
|
+
bundler (>= 1.15.0)
|
|
139
|
+
railties (= 7.0.8.1)
|
|
140
|
+
rails-dom-testing (2.2.0)
|
|
141
|
+
activesupport (>= 5.0.0)
|
|
142
|
+
minitest
|
|
143
|
+
nokogiri (>= 1.6)
|
|
144
|
+
rails-html-sanitizer (1.6.0)
|
|
145
|
+
loofah (~> 2.21)
|
|
146
|
+
nokogiri (~> 1.14)
|
|
147
|
+
railties (7.0.8.1)
|
|
148
|
+
actionpack (= 7.0.8.1)
|
|
149
|
+
activesupport (= 7.0.8.1)
|
|
150
|
+
method_source
|
|
151
|
+
rake (>= 12.2)
|
|
152
|
+
thor (~> 1.0)
|
|
153
|
+
zeitwerk (~> 2.5)
|
|
154
|
+
rake (13.2.1)
|
|
155
|
+
rspec-core (3.13.0)
|
|
156
|
+
rspec-support (~> 3.13.0)
|
|
157
|
+
rspec-expectations (3.13.0)
|
|
158
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
159
|
+
rspec-support (~> 3.13.0)
|
|
160
|
+
rspec-mocks (3.13.0)
|
|
161
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
162
|
+
rspec-support (~> 3.13.0)
|
|
163
|
+
rspec-rails (6.1.2)
|
|
164
|
+
actionpack (>= 6.1)
|
|
165
|
+
activesupport (>= 6.1)
|
|
166
|
+
railties (>= 6.1)
|
|
167
|
+
rspec-core (~> 3.13)
|
|
168
|
+
rspec-expectations (~> 3.13)
|
|
169
|
+
rspec-mocks (~> 3.13)
|
|
170
|
+
rspec-support (~> 3.13)
|
|
171
|
+
rspec-support (3.13.1)
|
|
172
|
+
thor (1.3.1)
|
|
173
|
+
timeout (0.4.1)
|
|
174
|
+
tzinfo (2.0.6)
|
|
175
|
+
concurrent-ruby (~> 1.0)
|
|
176
|
+
websocket-driver (0.7.6)
|
|
177
|
+
websocket-extensions (>= 0.1.0)
|
|
178
|
+
websocket-extensions (0.1.5)
|
|
179
|
+
zeitwerk (2.6.13)
|
|
180
|
+
|
|
181
|
+
PLATFORMS
|
|
182
|
+
arm64-darwin
|
|
183
|
+
x86_64-linux
|
|
184
|
+
|
|
185
|
+
DEPENDENCIES
|
|
186
|
+
grpc-rest!
|
|
187
|
+
rspec-rails
|
|
188
|
+
|
|
189
|
+
BUNDLED WITH
|
|
190
|
+
2.5.6
|
data/README.md
CHANGED
|
@@ -79,7 +79,7 @@ plugins:
|
|
|
79
79
|
- name: rails
|
|
80
80
|
out: .
|
|
81
81
|
```
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
Then, you can run `buf generate` to generate the Ruby files. This will generate:
|
|
84
84
|
* the Protobuf Ruby files for grpc, in `app/gen`
|
|
85
85
|
* A new route file, in `config/routes/grpc.rb`
|
|
@@ -126,40 +126,24 @@ Rails.application.routes.draw do
|
|
|
126
126
|
end
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
If you're using [gruf](https://github.com/bigcommerce/gruf), as long as your Gruf controllers are loaded on application load, you don't have to do anything else - grpc-rest will automatically hook the callbacks up. If you're not, you have to tell GrpcRest about your server. An example might look like this:
|
|
132
|
-
|
|
133
|
-
```ruby
|
|
134
|
-
# grpc_setup.rb, a shared library file somewhere in the app
|
|
135
|
-
|
|
136
|
-
def grpc_server
|
|
137
|
-
s = GRPC::RpcServer.new
|
|
138
|
-
s.handle(MyImpl.new) # handler inheriting from your service class - see https://grpc.io/docs/languages/ruby/basics/
|
|
139
|
-
s
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# startup script for gRPC
|
|
129
|
+
## Caveats
|
|
143
130
|
|
|
144
|
-
|
|
145
|
-
server = grpc_server
|
|
146
|
-
server.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT'])
|
|
147
|
-
|
|
148
|
-
# Rails initializer
|
|
149
|
-
require "grpc_setup"
|
|
150
|
-
server = grpc_server
|
|
151
|
-
GrpcRest.register_server(server)
|
|
152
|
-
```
|
|
131
|
+
This gem does not currently support the full path expression capabilities of grpc-gateway or the Google [http proto](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto). It only supports very basic single wildcard globbing (`*`). Contributions are welcome for more complex cases if they are needed.
|
|
153
132
|
|
|
154
133
|
## To Do
|
|
155
134
|
|
|
156
|
-
*
|
|
157
|
-
* Install via homebrew and/or have the binary in the gem itself
|
|
135
|
+
* Replace Go implementation with Ruby (+ executable) once [service and method lookup](https://github.com/protocolbuffers/protobuf/pull/15817) is released.
|
|
158
136
|
|
|
159
137
|
## Contributing
|
|
160
138
|
|
|
161
139
|
Bug reports and pull requests are welcome on GitHub at https://github.com/flipp-oss/grpc-rest.
|
|
162
140
|
|
|
141
|
+
To regenerate Ruby protobuf code for tests, install the `grpc-tools` gem and run this from the base directory:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
grpc_tools_ruby_protoc -I=./protoc-gen-rails/testdata --proto_path=./protoc-gen-rails/google-deps --ruby_out=./spec --grpc_out=./spec ./protoc-gen-rails/testdata/test_service.proto
|
|
145
|
+
```
|
|
146
|
+
|
|
163
147
|
## License
|
|
164
148
|
|
|
165
149
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/grpc-rest.gemspec
CHANGED
data/lib/grpc_rest/version.rb
CHANGED
data/lib/grpc_rest.rb
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
+
require 'google/protobuf/well_known_types'
|
|
2
|
+
require 'grpc'
|
|
3
|
+
|
|
1
4
|
module GrpcRest
|
|
2
5
|
class << self
|
|
3
6
|
|
|
4
|
-
def register_server(server)
|
|
5
|
-
@server = server
|
|
6
|
-
end
|
|
7
|
-
|
|
8
7
|
def underscore(s)
|
|
9
8
|
GRPC::GenericService.underscore(s)
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
# Gets a sub record from a proto. If it doesn't exist, initialize it and set it to the proto,
|
|
13
12
|
# then return it.
|
|
14
|
-
def sub_field(proto, name)
|
|
13
|
+
def sub_field(proto, name, parameters)
|
|
15
14
|
existing = proto.public_send(name.to_sym)
|
|
16
15
|
return existing if existing
|
|
17
16
|
|
|
@@ -19,7 +18,11 @@ module GrpcRest
|
|
|
19
18
|
return nil if descriptor.nil?
|
|
20
19
|
|
|
21
20
|
klass = descriptor.submsg_name.split('.').map(&:camelize).join('::').constantize
|
|
22
|
-
|
|
21
|
+
params = klass.descriptor.to_a.map(&:name).to_h do |key|
|
|
22
|
+
[key, parameters.delete(key)]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sub_record = klass.new(params)
|
|
23
26
|
proto.public_send(:"#{name}=", sub_record)
|
|
24
27
|
sub_record
|
|
25
28
|
end
|
|
@@ -27,7 +30,7 @@ module GrpcRest
|
|
|
27
30
|
def assign_value(proto, path, value)
|
|
28
31
|
tokens = path.split('.')
|
|
29
32
|
tokens[0...-1].each do |path_seg|
|
|
30
|
-
proto = sub_field(proto, path_seg)
|
|
33
|
+
proto = sub_field(proto, path_seg, {})
|
|
31
34
|
return if proto.nil?
|
|
32
35
|
end
|
|
33
36
|
proto.public_send(:"#{tokens.last}=", value) if proto.respond_to?(:"#{tokens.last}=")
|
|
@@ -36,15 +39,22 @@ module GrpcRest
|
|
|
36
39
|
def map_wkt(proto, params)
|
|
37
40
|
proto.to_a.each do |descriptor|
|
|
38
41
|
field = descriptor.name
|
|
42
|
+
val = params[field]
|
|
43
|
+
next if val.nil?
|
|
44
|
+
|
|
39
45
|
case descriptor.subtype&.name
|
|
40
46
|
when 'google.protobuf.Struct'
|
|
41
|
-
params[field] = Google::Protobuf::Struct.from_hash(
|
|
47
|
+
params[field] = Google::Protobuf::Struct.from_hash(val)
|
|
42
48
|
when 'google.protobuf.Timestamp'
|
|
43
|
-
|
|
49
|
+
if val.is_a?(Numeric)
|
|
50
|
+
params[field] = Google::Protobuf::Timestamp.from_time(Time.at(val))
|
|
51
|
+
else
|
|
52
|
+
params[field] = Google::Protobuf::Timestamp.from_time(Time.new(val))
|
|
53
|
+
end
|
|
44
54
|
when 'google.protobuf.Value'
|
|
45
|
-
params[field] = Google::Protobuf::Value.from_ruby(
|
|
55
|
+
params[field] = Google::Protobuf::Value.from_ruby(val)
|
|
46
56
|
when 'google.protobuf.ListValue'
|
|
47
|
-
params[field] = Google::Protobuf::ListValue.from_a(
|
|
57
|
+
params[field] = Google::Protobuf::ListValue.from_a(val)
|
|
48
58
|
else
|
|
49
59
|
map_wkt(descriptor.subtype, params[field]) if descriptor.subtype
|
|
50
60
|
end
|
|
@@ -68,16 +78,14 @@ module GrpcRest
|
|
|
68
78
|
name_tokens = entry[:split_name]
|
|
69
79
|
value_to_use = parameters.delete(name_tokens.last)
|
|
70
80
|
if entry[:val]
|
|
71
|
-
|
|
81
|
+
regex = entry[:val].tr('*', '')
|
|
82
|
+
value_to_use = value_to_use.gsub(regex, '')
|
|
72
83
|
end
|
|
73
84
|
assign_value(request, entry[:name], value_to_use)
|
|
74
85
|
end
|
|
75
86
|
if body_string.present? && body_string != '*'
|
|
76
87
|
# we need to "splat" the body parameters into the given sub-record rather than into the top-level.
|
|
77
|
-
sub_record = sub_field(request, body_string)
|
|
78
|
-
sub_record.class.descriptor.to_a.map(&:name).each do |key|
|
|
79
|
-
sub_record.public_send(:"#{key}=", parameters.delete(key))
|
|
80
|
-
end
|
|
88
|
+
sub_record = sub_field(request, body_string, parameters)
|
|
81
89
|
end
|
|
82
90
|
end
|
|
83
91
|
|
|
@@ -106,11 +114,8 @@ module GrpcRest
|
|
|
106
114
|
end
|
|
107
115
|
|
|
108
116
|
def send_grpc_request(service, method, request)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
route = "/#{service_name}/#{method.classify}"
|
|
112
|
-
handler = @server.send(:rpc_handlers)[route.to_sym]
|
|
113
|
-
handler.call(request)
|
|
117
|
+
klass = service.constantize::Service.subclasses.first
|
|
118
|
+
klass.new.public_send(method, request)
|
|
114
119
|
end
|
|
115
120
|
|
|
116
121
|
def send_request(service, method, request)
|
|
@@ -39,6 +39,8 @@ type Route struct {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
var controllerTemplate = `
|
|
42
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
|
43
|
+
|
|
42
44
|
require 'grpc_rest'
|
|
43
45
|
class {{.ControllerName}}Controller < ActionController::Base
|
|
44
46
|
protect_from_forgery with: :null_session
|
|
@@ -116,9 +118,12 @@ func ProcessService(service *descriptorpb.ServiceDescriptorProto, pkg string) (F
|
|
|
116
118
|
}, routes, nil
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
var routeTemplate =
|
|
121
|
+
var routeTemplate = `# frozen_string_literal: true
|
|
122
|
+
|
|
123
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
|
124
|
+
|
|
120
125
|
{{range . -}}
|
|
121
|
-
{{.HttpMethod}}
|
|
126
|
+
{{.HttpMethod}} '{{.Path}}' => '{{.Controller}}#{{.MethodName}}'
|
|
122
127
|
{{end -}}
|
|
123
128
|
`
|
|
124
129
|
|
data/protoc-gen-rails/main.go
CHANGED
|
@@ -49,11 +49,13 @@ func main() {
|
|
|
49
49
|
files = append(files, fileResult)
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
if len(files) > 0 {
|
|
53
|
+
routeOutput, err := routeFile()
|
|
54
|
+
if err != nil {
|
|
55
|
+
log.Fatalf("%s", fmt.Errorf("error processing routes: %w", err))
|
|
56
|
+
}
|
|
57
|
+
files = append(files, routeOutput)
|
|
55
58
|
}
|
|
56
|
-
files = append(files, routeOutput)
|
|
57
59
|
|
|
58
60
|
// process registry
|
|
59
61
|
writeResponse(files)
|
|
@@ -33,7 +33,9 @@ func fileNames(directory string, appendDirectory bool, extension string) ([]stri
|
|
|
33
33
|
return nil
|
|
34
34
|
}
|
|
35
35
|
files = append(files, info)
|
|
36
|
-
|
|
36
|
+
if info.Name() != ".keep" {
|
|
37
|
+
fullPaths = append(fullPaths, path)
|
|
38
|
+
}
|
|
37
39
|
if err != nil {
|
|
38
40
|
fmt.Println("ERROR:", err)
|
|
39
41
|
}
|
|
@@ -89,6 +91,25 @@ func Test_Base(t *testing.T) {
|
|
|
89
91
|
runTest(t, "base", map[string]string{})
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
func Test_NoServices(t *testing.T) {
|
|
95
|
+
workdir, _ := os.Getwd()
|
|
96
|
+
tmpdir, err := os.MkdirTemp(workdir, "proto-test.")
|
|
97
|
+
if err != nil {
|
|
98
|
+
t.Fatal(err)
|
|
99
|
+
}
|
|
100
|
+
defer os.RemoveAll(tmpdir)
|
|
101
|
+
|
|
102
|
+
args := []string{
|
|
103
|
+
"-I.",
|
|
104
|
+
"--rails_out=" + tmpdir,
|
|
105
|
+
}
|
|
106
|
+
args = append(args, fmt.Sprintf("testdata/test.proto"))
|
|
107
|
+
protoc(t, args)
|
|
108
|
+
|
|
109
|
+
testDir := workdir + "/testdata/no_service"
|
|
110
|
+
assertEqualFiles(t, testDir, tmpdir)
|
|
111
|
+
}
|
|
112
|
+
|
|
92
113
|
func assertEqualFiles(t *testing.T, original, generated string) {
|
|
93
114
|
names, err := fileNames(original, false, "")
|
|
94
115
|
if err != nil {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
|
|
2
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
|
3
|
+
|
|
2
4
|
require 'grpc_rest'
|
|
3
5
|
class MyServiceController < ActionController::Base
|
|
4
6
|
protect_from_forgery with: :null_session
|
|
@@ -9,8 +11,7 @@ class MyServiceController < ActionController::Base
|
|
|
9
11
|
METHOD_PARAM_MAP = {
|
|
10
12
|
|
|
11
13
|
"test" => [
|
|
12
|
-
{name: "
|
|
13
|
-
{name: "repeated_string", val: nil, split_name:["repeated_string"]},
|
|
14
|
+
{name: "foobar", val: "blah/*", split_name:["foobar"]},
|
|
14
15
|
],
|
|
15
16
|
|
|
16
17
|
"test_2" => [
|
|
@@ -19,12 +20,15 @@ class MyServiceController < ActionController::Base
|
|
|
19
20
|
"test_3" => [
|
|
20
21
|
{name: "sub_record.sub_id", val: nil, split_name:["sub_record","sub_id"]},
|
|
21
22
|
],
|
|
23
|
+
|
|
24
|
+
"test_4" => [
|
|
25
|
+
],
|
|
22
26
|
}.freeze
|
|
23
27
|
|
|
24
28
|
def test
|
|
25
29
|
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
|
26
30
|
grpc_request = GrpcRest.init_request(Testdata::TestRequest, request.parameters.to_h.slice(*fields))
|
|
27
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test"], "
|
|
31
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test"], "", request.parameters)
|
|
28
32
|
render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request)
|
|
29
33
|
end
|
|
30
34
|
|
|
@@ -42,4 +46,11 @@ class MyServiceController < ActionController::Base
|
|
|
42
46
|
render json: GrpcRest.send_request("Testdata::MyService", "test_3", grpc_request)
|
|
43
47
|
end
|
|
44
48
|
|
|
49
|
+
def test_4
|
|
50
|
+
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
|
51
|
+
grpc_request = GrpcRest.init_request(Testdata::TestRequest, request.parameters.to_h.slice(*fields))
|
|
52
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test_4"], "*", request.parameters)
|
|
53
|
+
render json: GrpcRest.send_request("Testdata::MyService", "test_4", grpc_request)
|
|
54
|
+
end
|
|
55
|
+
|
|
45
56
|
end
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
|
4
|
+
|
|
5
|
+
get '/test/*foobar' => 'my_service#test'
|
|
6
|
+
post '/test2' => 'my_service#test_2'
|
|
7
|
+
post '/test3/*sub_id' => 'my_service#test_3'
|
|
8
|
+
post '/test4' => 'my_service#test_4'
|
|
File without changes
|
|
@@ -3,6 +3,8 @@ syntax = "proto3";
|
|
|
3
3
|
package testdata;
|
|
4
4
|
|
|
5
5
|
import "google/api/annotations.proto";
|
|
6
|
+
import "google/protobuf/struct.proto";
|
|
7
|
+
import "google/protobuf/timestamp.proto";
|
|
6
8
|
|
|
7
9
|
message TestRequest {
|
|
8
10
|
string test_id = 1;
|
|
@@ -10,6 +12,10 @@ message TestRequest {
|
|
|
10
12
|
repeated string repeated_string = 3;
|
|
11
13
|
SubRecord sub_record = 4;
|
|
12
14
|
SubRecord second_record = 5;
|
|
15
|
+
google.protobuf.Struct struct_field = 6;
|
|
16
|
+
google.protobuf.Timestamp timestamp_field = 7;
|
|
17
|
+
google.protobuf.ListValue list_value = 8;
|
|
18
|
+
google.protobuf.Value bare_value = 9;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
message SubRecord {
|
|
@@ -25,8 +31,7 @@ message TestResponse {
|
|
|
25
31
|
service MyService {
|
|
26
32
|
rpc Test(TestRequest) returns (TestResponse) {
|
|
27
33
|
option (google.api.http) = {
|
|
28
|
-
get: "/test/{blah
|
|
29
|
-
body: "*"
|
|
34
|
+
get: "/test/{foobar=blah/*}"
|
|
30
35
|
};
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -43,4 +48,11 @@ service MyService {
|
|
|
43
48
|
};
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
rpc Test4(TestRequest) returns (TestResponse) {
|
|
52
|
+
option (google.api.http) = {
|
|
53
|
+
post: "/test4",
|
|
54
|
+
body: '*'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# See https://github.com/rspec/rspec-rails/issues/1596#issuecomment-834282306
|
|
2
|
+
|
|
3
|
+
require_relative './spec_helper'
|
|
4
|
+
require_relative './test_service_services_pb'
|
|
5
|
+
|
|
6
|
+
class ServerImpl < Testdata::MyService::Service
|
|
7
|
+
def test(req)
|
|
8
|
+
Testdata::TestResponse.new(some_int: 1, full_response: req.to_json)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_2(req)
|
|
12
|
+
Testdata::TestResponse.new(some_int: 2, full_response: req.to_json)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_3(req)
|
|
16
|
+
Testdata::TestResponse.new(some_int: 3, full_response: req.to_json)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_4(req)
|
|
20
|
+
Testdata::TestResponse.new(some_int: 4, full_response: req.to_json)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
RSpec.describe MyServiceController, type: :request do
|
|
25
|
+
|
|
26
|
+
describe 'using get' do
|
|
27
|
+
it 'should be successful' do
|
|
28
|
+
get "/test/blah/xyz?test_id=abc"
|
|
29
|
+
expect(response).to be_successful
|
|
30
|
+
expect(response.parsed_body).to eq({
|
|
31
|
+
'some_int' => 1,
|
|
32
|
+
'full_response' => %({"testId":"abc","foobar":"xyz"})
|
|
33
|
+
})
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'using body parameter' do
|
|
38
|
+
it "should be successful" do
|
|
39
|
+
params = {
|
|
40
|
+
sub_id: "id1",
|
|
41
|
+
another_id: "id2"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
post '/test2?test_id=abc&foobar=xyz×tamp_field=2024-04-03+01:02:03+UTC', params: params, as: :json
|
|
45
|
+
expect(response).to be_successful
|
|
46
|
+
expect(response.parsed_body).to eq({
|
|
47
|
+
'some_int' => 2,
|
|
48
|
+
'full_response' => %({"testId":"abc","foobar":"xyz","secondRecord":{"subId":"id1","anotherId":"id2"},"timestampField":"2024-04-03T01:02:03Z"})
|
|
49
|
+
})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe 'using sub-record splat' do
|
|
55
|
+
it 'should be successful' do
|
|
56
|
+
post '/test3/xyz?test_id=abc'
|
|
57
|
+
expect(response).to be_successful
|
|
58
|
+
expect(response.parsed_body).to eq({
|
|
59
|
+
'some_int' => 3,
|
|
60
|
+
'full_response' => %({"testId":"abc","subRecord":{"subId":"xyz"}})
|
|
61
|
+
})
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe 'full body splat' do
|
|
66
|
+
it 'should be successful' do
|
|
67
|
+
params = {
|
|
68
|
+
test_id: 'abc',
|
|
69
|
+
foobar: 'xyz',
|
|
70
|
+
repeated_string: ['W', 'T', 'F'],
|
|
71
|
+
sub_record: {
|
|
72
|
+
sub_id: 'id1',
|
|
73
|
+
another_id: 'id2'
|
|
74
|
+
},
|
|
75
|
+
second_record: {
|
|
76
|
+
sub_id: 'id3',
|
|
77
|
+
another_id: 'id4'
|
|
78
|
+
},
|
|
79
|
+
struct_field: {
|
|
80
|
+
"str_key": "val",
|
|
81
|
+
"int_key": 123,
|
|
82
|
+
"bool_key": true,
|
|
83
|
+
"nil_key": nil,
|
|
84
|
+
"list_key": [
|
|
85
|
+
{
|
|
86
|
+
"inner_key": "inner_val"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
list_value: ['F', 'Y', 'I'],
|
|
91
|
+
bare_value: 45,
|
|
92
|
+
timestamp_field: '2024-04-03 01:02:03 UTC',
|
|
93
|
+
}
|
|
94
|
+
post '/test4', params: params, as: :json
|
|
95
|
+
expect(response).to be_successful
|
|
96
|
+
expect(response.parsed_body).to eq({
|
|
97
|
+
'some_int' => 4,
|
|
98
|
+
'full_response' => %({"testId":"abc","foobar":"xyz","repeatedString":["W","T","F"],"subRecord":{"subId":"id1","anotherId":"id2"},"secondRecord":{"subId":"id3","anotherId":"id4"},"structField":{"bool_key":true,"str_key":"val","nil_key":null,"list_key":[{"inner_key":"inner_val"}],"int_key":123},"timestampField":"2024-04-03T01:02:03Z","listValue":["F","Y","I"],"bareValue":45})
|
|
99
|
+
})
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe 'numeric timestamp' do
|
|
104
|
+
it 'should be successful' do
|
|
105
|
+
params = {
|
|
106
|
+
timestamp_field: 1712692452
|
|
107
|
+
}
|
|
108
|
+
post "/test4", params: params, as: :json
|
|
109
|
+
expect(response).to be_successful
|
|
110
|
+
expect(response.parsed_body).to eq({
|
|
111
|
+
'some_int' => 4,
|
|
112
|
+
'full_response' => %({"timestampField":"2024-04-09T19:54:12Z"})
|
|
113
|
+
})
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "action_controller/railtie"
|
|
4
|
+
|
|
5
|
+
class GrpcApp < Rails::Application
|
|
6
|
+
initializer(:host_config) do
|
|
7
|
+
Rails.application.config.hosts << "www.example.com"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
GrpcApp.initialize!
|
|
11
|
+
|
|
12
|
+
require 'rspec/rails'
|
|
13
|
+
|
|
14
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
15
|
+
|
|
16
|
+
RSpec.configure do |config|
|
|
17
|
+
config.full_backtrace = true
|
|
18
|
+
config.render_views
|
|
19
|
+
|
|
20
|
+
config.mock_with(:rspec) do |mocks|
|
|
21
|
+
mocks.yield_receiver_to_any_instance_implementation_blocks = true
|
|
22
|
+
mocks.verify_partial_doubles = true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require_relative '../protoc-gen-rails/testdata/base/app/controllers/my_service_controller'
|
|
27
|
+
Rails.application.routes.draw_paths.push("#{Rails.root}/protoc-gen-rails/testdata/base/config/routes")
|
|
28
|
+
Rails.application.routes.draw do
|
|
29
|
+
draw(:grpc)
|
|
30
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: test_service.proto
|
|
4
|
+
|
|
5
|
+
require 'google/protobuf'
|
|
6
|
+
|
|
7
|
+
require 'google/api/annotations_pb'
|
|
8
|
+
require 'google/protobuf/struct_pb'
|
|
9
|
+
require 'google/protobuf/timestamp_pb'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xdc\x02\n\x0bTestRequest\x12\x0f\n\x07test_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66oobar\x18\x02 \x01(\t\x12\x17\n\x0frepeated_string\x18\x03 \x03(\t\x12\'\n\nsub_record\x18\x04 \x01(\x0b\x32\x13.testdata.SubRecord\x12*\n\rsecond_record\x18\x05 \x01(\x0b\x32\x13.testdata.SubRecord\x12-\n\x0cstruct_field\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x33\n\x0ftimestamp_field\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nlist_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12*\n\nbare_value\x18\t \x01(\x0b\x32\x16.google.protobuf.Value\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"7\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t2\xdf\x02\n\tMyService\x12T\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/test/{foobar=blah/*}\x12U\n\x05Test2\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x06/test2:\rsecond_record\x12Z\n\x05Test3\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x1a/test3/{sub_record.sub_id}\x12I\n\x05Test4\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/test4:\x01*b\x06proto3"
|
|
13
|
+
|
|
14
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
pool.add_serialized_file(descriptor_data)
|
|
18
|
+
rescue TypeError
|
|
19
|
+
# Compatibility code: will be removed in the next major version.
|
|
20
|
+
require 'google/protobuf/descriptor_pb'
|
|
21
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
|
22
|
+
parsed.clear_dependency
|
|
23
|
+
serialized = parsed.class.encode(parsed)
|
|
24
|
+
file = pool.add_serialized_file(serialized)
|
|
25
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
|
26
|
+
imports = [
|
|
27
|
+
["google.protobuf.Struct", "google/protobuf/struct.proto"],
|
|
28
|
+
["google.protobuf.Timestamp", "google/protobuf/timestamp.proto"],
|
|
29
|
+
]
|
|
30
|
+
imports.each do |type_name, expected_filename|
|
|
31
|
+
import_file = pool.lookup(type_name).file_descriptor
|
|
32
|
+
if import_file.name != expected_filename
|
|
33
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
|
37
|
+
warn "This will become an error in the next major version."
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module Testdata
|
|
41
|
+
TestRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.TestRequest").msgclass
|
|
42
|
+
SubRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.SubRecord").msgclass
|
|
43
|
+
TestResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.TestResponse").msgclass
|
|
44
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
2
|
+
# Source: test_service.proto for package 'testdata'
|
|
3
|
+
|
|
4
|
+
require 'grpc'
|
|
5
|
+
require 'test_service_pb'
|
|
6
|
+
|
|
7
|
+
module Testdata
|
|
8
|
+
module MyService
|
|
9
|
+
class Service
|
|
10
|
+
|
|
11
|
+
include ::GRPC::GenericService
|
|
12
|
+
|
|
13
|
+
self.marshal_class_method = :encode
|
|
14
|
+
self.unmarshal_class_method = :decode
|
|
15
|
+
self.service_name = 'testdata.MyService'
|
|
16
|
+
|
|
17
|
+
rpc :Test, ::Testdata::TestRequest, ::Testdata::TestResponse
|
|
18
|
+
rpc :Test2, ::Testdata::TestRequest, ::Testdata::TestResponse
|
|
19
|
+
rpc :Test3, ::Testdata::TestRequest, ::Testdata::TestResponse
|
|
20
|
+
rpc :Test4, ::Testdata::TestRequest, ::Testdata::TestResponse
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Stub = Service.rpc_stub_class
|
|
24
|
+
end
|
|
25
|
+
end
|
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.7
|
|
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-04-
|
|
11
|
+
date: 2024-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: grpc
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '6.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec-rails
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
41
55
|
description:
|
|
42
56
|
email:
|
|
43
57
|
- daniel.orner@flipp.com
|
|
@@ -49,6 +63,8 @@ files:
|
|
|
49
63
|
- ".gitignore"
|
|
50
64
|
- CHANGELOG
|
|
51
65
|
- CODE_OF_CONDUCT.md
|
|
66
|
+
- Gemfile
|
|
67
|
+
- Gemfile.lock
|
|
52
68
|
- README.md
|
|
53
69
|
- grpc-rest.gemspec
|
|
54
70
|
- lib/grpc_rest.rb
|
|
@@ -66,7 +82,13 @@ files:
|
|
|
66
82
|
- protoc-gen-rails/main_test.go
|
|
67
83
|
- protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb
|
|
68
84
|
- protoc-gen-rails/testdata/base/config/routes/grpc.rb
|
|
85
|
+
- protoc-gen-rails/testdata/no_service/.keep
|
|
86
|
+
- protoc-gen-rails/testdata/test.proto
|
|
69
87
|
- protoc-gen-rails/testdata/test_service.proto
|
|
88
|
+
- spec/grpc_rest_spec.rb
|
|
89
|
+
- spec/spec_helper.rb
|
|
90
|
+
- spec/test_service_pb.rb
|
|
91
|
+
- spec/test_service_services_pb.rb
|
|
70
92
|
homepage: ''
|
|
71
93
|
licenses:
|
|
72
94
|
- MIT
|
|
@@ -90,4 +112,8 @@ rubygems_version: 3.4.10
|
|
|
90
112
|
signing_key:
|
|
91
113
|
specification_version: 4
|
|
92
114
|
summary: Generate Rails controllers and routes from gRPC definitions.
|
|
93
|
-
test_files:
|
|
115
|
+
test_files:
|
|
116
|
+
- spec/grpc_rest_spec.rb
|
|
117
|
+
- spec/spec_helper.rb
|
|
118
|
+
- spec/test_service_pb.rb
|
|
119
|
+
- spec/test_service_services_pb.rb
|