如何在Ballerina中转换记录类型并剔除空值可选字段?
问题
我对接的部分API仅接收已填充的节点,若请求负载中包含空值节点会返回错误。示例如下:
场景1:源数据含空值节点
{ "name": { "firstName": "John", "middleName": "Quincy", "lastName": "Smith", "title": "" } }
接收API支持title字段,但要求不传入空值的title节点,转换后的预期负载为:
{ "givenName": "John", "middleName": "Quincy", "surname": "Smith" }
场景2:源数据title字段有值
{ "name": { "firstName": "John", "middleName": "Quincy", "lastName": "Smith", "title": "Mr" } }
转换后的负载需包含该字段:
{ "givenName": "John", "middleName": "Quincy", "surname": "Smith", "title": "Mr" }
请问如何在Ballerina中实现该需求?
解决方案
在Ballerina中可以通过条件判断+动态结构构建实现该需求,核心是只将非空字段加入最终请求负载。以下是具体实现:
完整代码示例
import ballerina/json; import ballerina/io; // 定义源数据结构 type SourceName record { string firstName; string middleName; string lastName; string title?; // 标记为可选字段,对应可能为空的情况 }; type SourcePayload record { SourceName name; }; // 定义目标数据结构 type TargetPayload record { string givenName; string middleName; string surname; string title?; // 可选字段,仅当源数据非空时添加 }; // 转换逻辑函数 function transformPayload(SourcePayload source) returns TargetPayload { // 初始化必填字段的目标结构 TargetPayload target = { givenName: source.name.firstName, middleName: source.name.middleName, surname: source.name.lastName }; // 仅当title为非空字符串时,添加到目标结构(trim处理空格空值) if source.name.title is string && source.name.title.trim() != "" { target.title = source.name.title; } return target; } // 测试两种场景 public function main() { // 测试空title场景 SourcePayload sourceWithEmptyTitle = { name: { firstName: "John", middleName: "Quincy", lastName: "Smith", title: "" } }; io:println("空title转换结果: ", json:toString(transformPayload(sourceWithEmptyTitle))); // 测试有值title场景 SourcePayload sourceWithValidTitle = { name: { firstName: "John", middleName: "Quincy", lastName: "Smith", title: "Mr" } }; io:println("有值title转换结果: ", json:toString(transformPayload(sourceWithValidTitle))); }
代码说明
- 类型定义:用
record明确源数据和目标数据的结构,将可能为空的title标记为可选字段(?),适配字段存在或缺失的场景。 - 转换逻辑:先构建必填字段的基础目标结构,再通过条件判断检查源数据的
title是否为非空字符串(加入trim()处理纯空格的空值情况),满足条件则添加该字段到目标结构。 - 场景测试:在
main函数中分别验证两种场景,输出转换后的JSON结果,确保符合预期。
扩展优化(多字段复用)
如果需要处理多个可能为空的字段,可以封装通用的非空字段添加函数,提升代码复用性:
// 通用函数:仅当值非空时添加到目标map function addNonEmptyField(map<anydata> target, string key, string? value) { if value is string && value.trim() != "" { target[key] = value; } }
调用方式:
function transformPayload(SourcePayload source) returns TargetPayload { map<anydata> targetMap = { "givenName": source.name.firstName, "middleName": source.name.middleName, "surname": source.name.lastName }; addNonEmptyField(targetMap, "title", source.name.title); // 可添加更多字段处理,比如addNonEmptyField(targetMap, "suffix", source.name.suffix); return targetMap.cloneWithType(); }
这种方式更适合多字段的复杂转换场景,减少重复代码。
内容的提问来源于stack exchange,提问作者Dilan Sachintha Nayanajith
相关产品推荐
相关产品推荐

