Skip to content

fix(gengateway): correct body field decoding in opaque API mode#6197

Merged
johanbrandhorst merged 1 commit intogrpc-ecosystem:mainfrom
kop:fix_opaque_api_body_decoding
Dec 26, 2025
Merged

fix(gengateway): correct body field decoding in opaque API mode#6197
johanbrandhorst merged 1 commit intogrpc-ecosystem:mainfrom
kop:fix_opaque_api_body_decoding

Conversation

@kop
Copy link
Copy Markdown
Contributor

@kop kop commented Dec 26, 2025

References to other Issues or PRs

Fixes #6189

Have you read the Contributing Guidelines?

Yes

Brief description of what is fixed or changed

When use_opaque_api is enabled with a body field mapping (e.g., body: "field_name"), the generated code was incorrectly decoding the HTTP request body as the full request message type instead of the specific field's message type.

This fix:

  • Adds GetBodyFieldType() helper to determine the body field's type
  • Updates template to decode into the field type and pass it directly to the setter method

Other comments

I added OpaqueCreateProduct and OpaqueCreateProductField to opaque.proto to act as a test case.

Generated code shows the difference. Note var bodyData OpaqueCreateProductRequest vs bodyData := &OpaqueProduct{}.

func request_OpaqueEcommerceService_OpaqueCreateProduct_0(ctx context.Context, marshaler runtime.Marshaler, client OpaqueEcommerceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
	var (
		protoReq OpaqueCreateProductRequest
		metadata runtime.ServerMetadata
	)
	var bodyData OpaqueCreateProductRequest
	if err := marshaler.NewDecoder(req.Body).Decode(&bodyData); err != nil && !errors.Is(err, io.EOF) {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	protoReq = bodyData
	if req.Body != nil {
		_, _ = io.Copy(io.Discard, req.Body)
	}
	msg, err := client.OpaqueCreateProduct(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
	return msg, metadata, err
}

vs

func request_OpaqueEcommerceService_OpaqueCreateProductField_0(ctx context.Context, marshaler runtime.Marshaler, client OpaqueEcommerceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
	var (
		protoReq OpaqueCreateProductFieldRequest
		metadata runtime.ServerMetadata
	)
	bodyData := &OpaqueProduct{}
	if err := marshaler.NewDecoder(req.Body).Decode(bodyData); err != nil && !errors.Is(err, io.EOF) {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	protoReq.SetProduct(bodyData)
	if req.Body != nil {
		_, _ = io.Copy(io.Discard, req.Body)
	}
	if err := req.ParseForm(); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_OpaqueEcommerceService_OpaqueCreateProductField_0); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	msg, err := client.OpaqueCreateProductField(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
	return msg, metadata, err
}

When `use_opaque_api` is enabled with a body field mapping (e.g., `body: "field_name"`), the generated code was incorrectly decoding the HTTP request body as the full request message type instead of the specific field's message type.

This fix:
- Adds GetBodyFieldType() helper to determine the body field's type
- Updates template to decode into the field type and pass it directly to the setter method

Fixes grpc-ecosystem#6189
Copy link
Copy Markdown
Collaborator

@johanbrandhorst johanbrandhorst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick fix! The bazel error seems unrelated, I expect it will go away.

@johanbrandhorst johanbrandhorst merged commit 11fc3b8 into grpc-ecosystem:main Dec 26, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

use_opaque_api decodes the request body incorrectly

2 participants