alirezashamsabad opened a new pull request, #13812:
URL: https://github.com/apache/apisix/pull/13812
### Description
Today a Route using `grpc-transcode` is bound to exactly one gRPC method
through
`service` and `method`, so a service with ten methods needs ten Routes. That
duplicates
configuration the proto usually already declares via `google.api.http`
annotations.
This adds an optional `use_http_annotations` flag. When enabled, the plugin
reads those
annotations and selects the method whose path template and HTTP method match
the request.
One Route can then serve a whole annotated service:
```json
{
"uri": "/api/v1/*",
"plugins": {
"grpc-transcode": { "proto_id": "1", "use_http_annotations": true }
},
"upstream": { "scheme": "grpc", "type": "roundrobin", "nodes": {
"127.0.0.1:50051": 1 } }
}
```
`GET /api/v1/items/42` reaches `ItemService/GetItem` with `id` bound to
`42`, and
`POST /api/v1/items` reaches `ItemService/CreateItem`, without per-method
Routes.
#### Which issue(s) this PR fixes:
Relates to [#3406](https://github.com/apache/apisix/issues/3406), which was
closed as
not planned before any implementation existed. This PR provides one, with
tests and
documentation, so the trade-offs can be judged concretely.
### What is supported
- Path templates per the `google.api.http` grammar: literals, `{var}`,
`{var=*}`,
`{var=a/*/b}`, `**`, nested field paths such as `{user.id}`, and a
trailing `:verb`
- `additional_bindings`
- `body` semantics: omitted means the payload is not read; `"*"` means the
whole payload
is the message; `"<field>"` maps the payload to that field and leaves
siblings to the
query string
- Path-captured values override query or body values for the same field
- Match precedence: more literal segments, then fewer variables, then
service/method name.
`:verb` is matched separately and is not part of the ranking
- While the flag is on, configured `service` and `method` are ignored
### Backwards compatibility
The flag defaults to `false`. When it is off, `service` and `method` stay
mandatory, so
existing configs and validation errors are unchanged.
Behavior change in both modes: `access` returns `503` when the proto cannot
be loaded.
Previously the request was forwarded untranscoded and often surfaced as a
confusing
upstream `405`. The gateway now fails closed and logs the reason.
### Notes for reviewers
- **Binary descriptor sets only.** Annotations are preserved only in a
descriptor set from
`protoc --include_imports --descriptor_set_out=...`. A plain `.proto`
uploaded to
`/apisix/admin/protos` cannot resolve `google/api/annotations.proto`.
- **No new dependency.** Pinned lua-protobuf 0.5.3 exposes the extension as
`method.options.http`.
- **Vendored test protos.**
`t/grpc_server_example/proto/google/api/{annotations,http}.proto`
are checked in for the fixture descriptor set (Apache-2.0 under Google's
copyright;
listed in `LICENSE` and ignored in `.licenserc.yaml`).
- **Limitation:** `body` supports a top-level field name only (not `body:
"item.nested"`).
- **Out of scope:** an intermittent `failed to find proto by id` can still
occur while
the etcd config sync is in flight. It reproduces on legacy
`service`/`method` routes
as well, and its cause is distinct from the type mismatch in
[#8952](https://github.com/apache/apisix/issues/8952). I have not
root-caused it, so
it is not addressed here.
### Tests
`t/plugin/grpc-transcode-http-annotations.t` covers path-template parsing
and rejection,
end-to-end routing, `body` modes, `:verb`, path-over-query/body, `404`,
`405` with
`Allow`, `400`, `503`, `proxy-rewrite`, and rebuilding the table after proto
replacement.
`t/plugin/grpc-transcode*.t` passes (297 assertions).
Developed with AI assistance; design decisions, review and testing are my
own.
### Checklist
- [x] I have explained the need for this PR and the problem it solves
- [x] I have explained the changes or the new features added to this PR
- [x] I have added tests corresponding to this change
- [x] I have updated the documentation to reflect this change
- [x] I have verified that this change is backward compatible (If it is not
backward compatible, please discuss on the [APISIX mailing
list](https://github.com/apache/apisix/tree/master#community) first)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]