grpc-rest 0.1.17 → 0.1.19

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: c9364ed8060e0d6d89f6082f0da592a34adb7977c36b776be56ee8e816bf9575
4
- data.tar.gz: 8358915b2c4cea7d0950fb9198395b11d70a94e8800e3e52f9781bfcf18707be
3
+ metadata.gz: 3c9a0fd0dc8a21c8ff8e5103a6bdffe98cc51cb522fb8dac59a65b2e9ceacc7c
4
+ data.tar.gz: a42ae7274e7a9db0161e3a40374d050a334312c742d8737652ab8fd8aaa55ec4
5
5
  SHA512:
6
- metadata.gz: cfaea51fd7addb1aedc0c3f4c7ea8450af57716c146d46342331d52c4d6df56df835609477692c3c8ec0985f5164f82be7b0261f60a7241b2723b6aa9c62f8ba
7
- data.tar.gz: 665cf40abf886db39d3c34d253b1eeb457a3b204d8c254a0737cdb41b8e754a7c1d2f2159bccdf89a8d1efdad075d10b67982bac23d2cbf5c1238510449c1280
6
+ metadata.gz: 624a27f0b5345256376d3a3cbd418543339d9f604ef42866da442a4589fd0732702b61e02f37d14e31b1cb53f5d707d73a8924af45df9be65995942316b75d86
7
+ data.tar.gz: d548c211f158b8095ec655691e11c1cb815382ecdfce8a42ed014fdcf82d5286e333d2894a8c5bdb3564b861beba29387b2936a39c6d28108e7d3d472da6ff45
data/CHANGELOG CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 0.1.19 - 2024-08-22
11
+
12
+ - Add `emit_defaults` extension for JSON responses.
13
+
14
+ # 0.1.18 - 2024-08-15
15
+ - Automatically add prefixes to enum values if not provided
16
+
10
17
  # 0.1.17 - 2024-07-30
11
18
  - Ignore unknown fields in JSON decoding
12
19
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grpc-rest (0.1.17)
4
+ grpc-rest (0.1.19)
5
5
  grpc
6
6
  rails (>= 6.0)
7
7
 
data/README.md CHANGED
@@ -130,9 +130,32 @@ end
130
130
 
131
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.
132
132
 
133
+ ## Proto Options
134
+
135
+ By default, grpc-rest uses the Protobuf default of omitting empty values on response. You can change this behavior by using an OpenAPI extension with the key `x-grpc-rest-emit-defaults`:
136
+
137
+ ```protobuf
138
+ service MyService {
139
+ rpc Test(MyRequest) returns (MyResponse) {
140
+ option (google.api.http) = {
141
+ get: "/test/"
142
+ };
143
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
144
+ extensions: {
145
+ key: 'x-grpc-rest-emit-defaults';
146
+ value: {
147
+ bool_value: true;
148
+ }
149
+ }
150
+ };
151
+ }
152
+ }
153
+ ```
154
+
155
+
133
156
  ## To Do
134
157
 
135
- * Replace Go implementation with Ruby (+ executable) once [service and method lookup](https://github.com/protocolbuffers/protobuf/pull/15817) is released.
158
+ * Replace Go implementation with Ruby (+ executable)
136
159
 
137
160
  ## Contributing
138
161
 
@@ -1,3 +1,3 @@
1
1
  module GrpcRest
2
- VERSION = '0.1.17'
2
+ VERSION = '0.1.19'
3
3
  end
data/lib/grpc_rest.rb CHANGED
@@ -37,12 +37,45 @@ module GrpcRest
37
37
  proto.public_send(:"#{tokens.last}=", value) if proto.respond_to?(:"#{tokens.last}=")
38
38
  end
39
39
 
40
+ # https://stackoverflow.com/a/2158473/5199431
41
+ def longest_common_substring(arr)
42
+ return "" if arr.empty?
43
+
44
+ result = 0
45
+ first_val = arr[0]
46
+ (0...first_val.length).each do |k|
47
+ all_matched = true
48
+ character = first_val[k]
49
+ arr.each { |str| all_matched &= (character == str[k]) }
50
+ break unless all_matched
51
+ result += 1
52
+ end
53
+ first_val.slice(0, result)
54
+ end
55
+
56
+ def handle_enum_values(descriptor, value)
57
+ names = descriptor.subtype.to_h.keys.map(&:to_s)
58
+ prefix = longest_common_substring(names)
59
+ if prefix.present? && !value.starts_with?(prefix)
60
+ "#{prefix}#{value}"
61
+ else
62
+ value
63
+ end
64
+ end
65
+
40
66
  def map_proto_type(proto, params)
41
67
  proto.to_a.each do |descriptor|
42
68
  field = descriptor.name
43
69
  val = params[field]
44
70
  next if val.nil?
45
- next if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
71
+ if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
72
+ if descriptor.label == :repeated
73
+ params[field] = val.map { |v| handle_enum_values(descriptor, v)}
74
+ else
75
+ params[field] = handle_enum_values(descriptor, val)
76
+ end
77
+ next
78
+ end
46
79
 
47
80
  case descriptor.type
48
81
  when *%i(int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64)
@@ -179,7 +212,7 @@ module GrpcRest
179
212
  klass.new.public_send(method, request)
180
213
  end
181
214
 
182
- def send_request(service, method, request)
215
+ def get_response(service, method, request)
183
216
  if defined?(Gruf)
184
217
  service_obj = service.constantize::Service
185
218
  klass = ::Gruf::Controllers::Base.subclasses.find do |k|
@@ -191,6 +224,15 @@ module GrpcRest
191
224
  end
192
225
  send_grpc_request(service, method, request)
193
226
  end
227
+
228
+ def send_request(service, method, request, options={})
229
+ response = get_response(service, method, request)
230
+ if options[:emit_defaults]
231
+ response.to_json(emit_defaults: true)
232
+ else
233
+ response
234
+ end
235
+ end
194
236
  end
195
237
 
196
238
  end
@@ -5,17 +5,21 @@ go 1.22.0
5
5
  require (
6
6
  github.com/iancoleman/strcase v0.3.0
7
7
  github.com/stretchr/testify v1.8.4
8
- google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641
9
- google.golang.org/protobuf v1.32.0
8
+ google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280
9
+ google.golang.org/protobuf v1.34.2
10
10
  )
11
11
 
12
12
  require (
13
13
  github.com/davecgh/go-spew v1.1.1 // indirect
14
14
  github.com/google/go-cmp v0.6.0 // indirect
15
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
15
16
  github.com/kr/pretty v0.3.1 // indirect
16
17
  github.com/pmezard/go-difflib v1.0.0 // indirect
17
18
  github.com/rogpeppe/go-internal v1.12.0 // indirect
19
+ golang.org/x/text v0.17.0 // indirect
18
20
  google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
21
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240820151423-278611b39280 // indirect
22
+ google.golang.org/grpc v1.65.0 // indirect
19
23
  gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
20
24
  gopkg.in/yaml.v3 v3.0.1 // indirect
21
25
  )
@@ -3,6 +3,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
3
3
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4
4
  github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
5
5
  github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
7
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
6
8
  github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
7
9
  github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
8
10
  github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -20,14 +22,26 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
20
22
  github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
21
23
  github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
22
24
  github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
25
+ golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
26
+ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
23
27
  google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
24
28
  google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
25
29
  google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe h1:0poefMBYvYbs7g5UkjS6HcxBPaTRAmznle9jnxYoAI8=
26
30
  google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
27
31
  google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641 h1:SO1wX9btGFrwj9EzH3ocqfwiPVOxfv4ggAJajzlHA5s=
28
32
  google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641/go.mod h1:wLupoVsUfYPgOMwjzhYFbaVklw/INms+dqTp0tc1fv8=
33
+ google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
34
+ google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
35
+ google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280 h1:YDFM9oOjiFhaMAVgbDxfxW+66nRrsvzQzJ51wp3OxC0=
36
+ google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
37
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240820151423-278611b39280 h1:XQMA2e105XNlEZ8NRF0HqnUOZzP14sUSsgL09kpdNnU=
38
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240820151423-278611b39280/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
39
+ google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
40
+ google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
29
41
  google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
30
42
  google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
43
+ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
44
+ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
31
45
  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
32
46
  gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
33
47
  gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -0,0 +1,44 @@
1
+ syntax = "proto3";
2
+
3
+ package grpc.gateway.protoc_gen_openapiv2.options;
4
+
5
+ import "google/protobuf/descriptor.proto";
6
+ import "protoc-gen-openapiv2/options/openapiv2.proto";
7
+
8
+ option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options";
9
+
10
+ extend google.protobuf.FileOptions {
11
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
12
+ //
13
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
14
+ // different descriptor messages.
15
+ Swagger openapiv2_swagger = 1042;
16
+ }
17
+ extend google.protobuf.MethodOptions {
18
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
19
+ //
20
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
21
+ // different descriptor messages.
22
+ Operation openapiv2_operation = 1042;
23
+ }
24
+ extend google.protobuf.MessageOptions {
25
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
26
+ //
27
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
28
+ // different descriptor messages.
29
+ Schema openapiv2_schema = 1042;
30
+ }
31
+ extend google.protobuf.ServiceOptions {
32
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
33
+ //
34
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
35
+ // different descriptor messages.
36
+ Tag openapiv2_tag = 1042;
37
+ }
38
+ extend google.protobuf.FieldOptions {
39
+ // ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
40
+ //
41
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
42
+ // different descriptor messages.
43
+ JSONSchema openapiv2_field = 1042;
44
+ }