Skip to content

Conversation

@bytelazy
Copy link

@bytelazy bytelazy commented Oct 4, 2025

Description

In the grpc-transcode plugin, when a repeated field in the gRPC response is empty, it is incorrectly encoded as an empty JSON object ({}) instead of an empty JSON array ([]). This behavior does not comply with the gRPC-JSON transcoding specification and can cause type-related errors on the client-side, which expects an array.

Fixes #11440

Checklist

Changes or the new features added to this PR
The main changes are in the response.lua file to correctly handle the serialization of repeated fields.

Identify repeated fields: A new function fetch_proto_array_names has been added. It recursively traverses the loaded Protobuf schema definition to identify and collect the names of all fields marked as repeated.

Ensure correct JSON array serialization:

A new function set_default_array has been introduced. After the gRPC response is decoded into a Lua table, this function traverses the table.

For any field that was identified as repeated, it sets a specific metatable (core.json.array_mt).

This metatable forces the core.json.encode function to serialize the corresponding Lua table as a JSON array ([]), even when it is empty.

This logic is applied just before the decoded response is encoded into the final JSON output, ensuring the structure is correct.

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Oct 4, 2025
@Baoyuantop
Copy link
Contributor

Hi @bytelazy, could you merge the latest main branch?

@bytelazy
Copy link
Author

Hi @bytelazy, could you merge the latest main branch?

sure~

@membphis
Copy link
Member

pls merge the master branch,

fix the ci case:
#12761

if type(v) == "table" then
local sub_names = fetch_proto_array_names(v)
for sub_name,_ in pairs(sub_names) do
names[sub_name] = 1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
names[sub_name] = 1
names[sub_name] = true

local PROTOBUF_REPEATED_LABEL = 3
local repeated_label = PROTOBUF_REPEATED_LABEL

local function fetch_proto_array_names(proto_obj)
Copy link
Member

Choose a reason for hiding this comment

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

This function does not take into account the possibility of duplicate names in nested fields, for example:

message Company {
    repeated string name = 1;
}
message HelloRequest {
    string name = 1;
    Company company = 2;
}


local function fetch_proto_array_names(proto_obj)
local names = {}
if type(proto_obj) == "table" then
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if type(proto_obj) == "table" then
if type(proto_obj) ~= "table" then
return
end

return err_msg
end

local array_names = fetch_proto_array_names(proto)
Copy link
Contributor

Choose a reason for hiding this comment

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

We can cache it without having to reprocess it every time a request is made.

local function create_proto_obj(proto_id)

@Baoyuantop Baoyuantop added the wait for update wait for the author's response in this issue/PR label Dec 3, 2025
@Baoyuantop
Copy link
Contributor

Hi @bytelazy, please check these comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:M This PR changes 30-99 lines, ignoring generated files. wait for update wait for the author's response in this issue/PR

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

bug: grpc-transcode cant transcode empty array list to [] , but it did to {}

5 participants