zhoujiexiong commented on issue #11440:
URL: https://github.com/apache/apisix/issues/11440#issuecomment-2257496327

   > > @wenhaoZhao1997
   > > May be there is a quick workaround: (mainly to prevent ambiguity of JSON 
object/array for the frontend)
   > > 
   > > 1. set `no_default_values` pb_option of the plugin
   > >    
https://apisix.apache.org/docs/apisix/plugins/grpc-transcode/#options-for-pb_option
   > >    with the option, the empty array field would be presented like this:
   > >    ```json
   > >    {
   > >        "items": {}
   > >    }
   > >    ```
   > >    
   > >    
   > >        
   > >          
   > >        
   > >    
   > >          
   > >        
   > >    
   > >        
   > >      
   > >    --->
   > >    ```
   > >    {}
   > >    ```
   > >    
   > >    
   > >        
   > >          
   > >        
   > >    
   > >          
   > >        
   > >    
   > >        
   > >      
   > >    see also: 
https://github.com/starwing/lua-protobuf?tab=readme-ov-file#options
   > >    auto_default_values(default) - act as `use_default_values` for 
`proto3` and act as `no_default_values` for the others
   > > 2. at the frontend, test the `items` field if `undefined` or not
   > 
   > thx for your reply, yes i have tried pb_option no_default_values , and its 
indeed a solution. and i want to know wheather its a plugin lua code problem 
(when decoding proto file)or smth. if its a bug ,why didn't anyone else find 
out before.
   
   I think PR is needed. :D
   
   The response logic/flow of the plugin at body_filter phase are simply like 
so:
   1. `pb.decode` bytes stream from upstream to LUA table/object
      
   2. `cjson.encode` the `object` to bytes stream then reply it to downstream
   
      Though `cjson.decode_array_with_array_mt(true)` is the default setting, 
but
      the `object` is decoded by `pb.decode`, without which tagging a table as 
a JSON array in case it is empty(for more to see FYI below).
   
      So cjson.encode output `{}` but not the expected `[]`.
   
      FYI:
      ```lua
      --- decode_array_with_array_mt
      ---
      --- If enabled, JSON Arrays decoded by cjson.decode will result in Lua 
tables
      --- with the array_mt metatable. This can ensure a 1-to-1 relationship 
between
      --- arrays upon multiple encoding/decoding of your JSON data with this 
module.
      ---
      --- If disabled, JSON Arrays will be decoded to plain Lua tables, without 
the
      --- `cjson.array_mt` metatable.
      ---
      --- ## Example
      ---
      ---```lua
      --- local cjson = require "cjson"
      ---
      --- -- default behavior
      --- local my_json = [[{"my_array":[]}]]
      --- local t = cjson.decode(my_json)
      --- cjson.encode(t) -- {"my_array":{}} back to an object
      ---
      --- -- now, if this behavior is enabled
      --- cjson.decode_array_with_array_mt(true)
      ---
      --- local my_json = [[{"my_array":[]}]]
      --- local t = cjson.decode(my_json)
      --- cjson.encode(t) -- {"my_array":[]} properly re-encoded as an array
      ---```
      ---
      --- **NOTE:** This function is specific to the OpenResty cjson fork.
      ---
      ---@param enabled boolean # (default: false)
      function cjson.decode_array_with_array_mt(enabled) end
      ```
     
   
   One of the solutions could be like this(FYR):
   1. `pb.hook` to hook the ouput of `pb.decode`
   2. at the hook function, traversal the fields of the `decoded object` 
recursively
   3. setmetatable(`EMPTY_FIELD_WITH_repeated_LABEL`, cjson.empty_array_mt)
   


-- 
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]

Reply via email to