type-conversionballerina

How to transform a record to a different record type with some fields being optional in Ballerina?


A number of API's that I work with expect to receive only populated nodes. If a node's data is empty and that node is part of the posting payload, an error is returned.
For instance, with this source information:

{
    "name": {
        "firstName": "John",
        "middleName": "Quincy",
        "lastName": "Smith",
        "title": ""
    }
}

the receiving API may support title, but expects that no empty title node would be presented, the hypothetical transformed payload would be something like:

{
    "givenName": "John",
    "middleName": "Quincy",
    "surname": "Smith"
}

whereas if title is populated in the source, it should also be included in the target:

{
    "name": {
        "firstName": "John",
        "middleName": "Quincy",
        "lastName": "Smith",
        "title": "Mr"
    }
}

transforms to:

{
    "givenName": "John",
    "middleName": "Quincy",
    "surname": "Smith",
    "title": "Mr"
}

How can this be achieved in Ballerina?


Solution

  • You can do it like this.

    type Input record {|
        record {|
            string firstName;
            string middleName;
            string lastName;
            string title;
        |} name;
    |};
    
    type Transformed record {|
        string givenName;
        string middleName;
        string surname;
        string title?;
    |};
    
    function transform(Input input) returns Transformed =>
        let var {firstName, middleName, lastName, title} = input.name in {
            givenName: firstName,
            // same as `middleName: middleName,`
            middleName,
            surname: lastName,
            // setting `()` as the value results in the field not being set 
            // when the field is an optional field in the record that is not of an optional type
            title: title.trim() == "" ? () : title
        };