appsmith icon indicating copy to clipboard operation
appsmith copied to clipboard

[Task]: Consume map of autogenerated names and actual binding parameters and ensure compatibility

Open subrata71 opened this issue 2 years ago • 4 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Summary

As part of the Datatype Handling project, the client-side will send the possible data type of each binding parameter along with its value. The client-side will send such payload with the autogenerated name of the actual binding parameter with a view to reducing the payload size.

Why should this be worked on?

The client-side will send the possible data type (JS Type) of each binding parameter along with its value. The client-side will send such payload with the autogenerated name of the actual binding parameter with a view to reducing the payload size. The client-side will also send the mapping between the autogenerated name and the actual binding parameter name in a different part called parameterMap. The sample request with three binding parameters would look as follows:

------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="executeActionDTO"

{"actionId":"627a09673b06f26463e16ba8","viewMode":false, "paramProperties": [{"k1": "STRING"}, {"k2": "NULL"}, {"k3": "NULL"}]}
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="parameterMap"

{"k1":"Text1.text","k2":"Table1.data", "k3": "Api1.data"}
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k1" filename="blob"
Content-Type: text/plain
abc
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k2"; filename="blob"
Content-Type: text/plain

null
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k3"; filename="blob"
Content-Type: text/plain

null
------WebKitFormBoundaryj9bhZXa3DECRp83J--

In this task, the server will consume this new payload and will not apply any logic to the identification of the data type rather it will use the parameterMap in order to decode the original binding parameter's name. It also needs to be ensured that the change in the action execution request body payload doesn't break any existing implementation and hence ensuring compatibility.

subrata71 avatar Jul 30 '22 12:07 subrata71

In order to consume the above payload the model ExecuteActionDTO needs to be changed like below:

public class ExecuteActionDTO {

    String actionId;

    List<Param> params;

    PaginationField paginationField;

    Boolean viewMode = false;

    Map<String, String> paramProperties; //e.g. "paramProperties": {"k1": "STRING", "k2": "NULL","k3": "NULL"}

    Map<String, String> parameterMap; //e.g. {"Text1.text": "k1","Table1.data": "k2", "Api1.data": "k3"}
    Map<String, String> invertParameterMap; //e.g. {"k1":"Text1.text","k2":"Table1.data", "k3": "Api1.data"}

    public void setParameterMap(Map<String, String> parameterMap) {
        this.parameterMap = parameterMap;
        invertParameterMap = parameterMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getValue,
                        Map.Entry::getKey
                ));
    }
}

Note

The equivalent Java object after the deserialization actually looks like List<Map<String,String>> . But List<Map<String,String>> doesn’t help much if we want to know the data type of a particular binding. That’s why I converted List<Map<String,String>> to one single flat map i.e. Map<String, String> as it’s guaranteed that the autogenerated names will be unique.

cc: @nidhi-nair @ChandanBalajiBP

subrata71 avatar Aug 02 '22 07:08 subrata71

After this change has been implemented both on the client and the server-side do we expect the paramProperties will always exist in the payload even if it's an empty array? @nidhi-nair @ChandanBalajiBP

subrata71 avatar Aug 03 '22 06:08 subrata71

We have decided to go with this structure instead as it helps the server to do less effort with respect to deserialization.

------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="executeActionDTO"

{"actionId":"627a09673b06f26463e16ba8","viewMode":false, "paramProperties": {"k1": "STRING", "k2": "NULL","k3": "NULL"}}
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="parameterMap"

{"Text1.text": "k1","Table1.data": "k2", "Api1.data": "k3"}
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k1" filename="blob"
Content-Type: text/plain
abc
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k2"; filename="blob"
Content-Type: text/plain

null
------WebKitFormBoundaryj9bhZXa3DECRp83J
Content-Disposition: form-data; name="k3"; filename="blob"
Content-Type: text/plain

null
------WebKitFormBoundaryj9bhZXa3DECRp83J--

cc: @nidhi-nair @ChandanBalajiBP

subrata71 avatar Aug 04 '22 07:08 subrata71

Test Plan

The regression test suffices as this is a compatibility change.

subrata71 avatar Aug 09 '22 08:08 subrata71

A demonstration of this delivery is documented here.

subrata71 avatar Aug 11 '22 17:08 subrata71