English
Fx.object
About 5952 wordsAbout 20 min
2026-04-10
Scope:
Table of Contents
Summary
The overview of this document is as follows: This document introduces the API definitions of Fx.object, usage methods, and related notes. It serves as the primary entry document for Fx.object and focuses on improving structure consistency and navigation clarity.
Data Creation
| Method | Description | Signature |
|---|---|---|
create | Create parent and child data together | Fx.object.create(String apiName, Map objectData, Map details, CreateAttribute createAttribute) |
batchCreate | Batch create, up to 500 rows per batch | Fx.object.batchCreate(String apiName, List objects, CreateAttribute attribute) |
copyByRule | Create data by mapping rule | Fx.object.copyByRule(String sourceApiName, String sourceId, String ruleApiName, Map masterPlus, Map detailPlus) |
create
Create parent and child data together.
Fx.object.create(String apiName, Map objectData, Map details, CreateAttribute createAttribute)
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
apiName | String | Yes | Parent object API Name |
objectData | Map | Yes | Parent object field values |
details | Map | Yes | Child-object data keyed by child API Name |
createAttribute | CreateAttribute | Yes | Creation control attributes |
Return:
isError/error: whether an error occurreddata: created resultmessage: prompt message
Notes:
- Passing empty
detailsmeans no child data is created - Duplicate-check interception may still enter the error branch, and duplicate details should be read from
data
Minimal example:
Map masterData = ["name": "Master-detail create 1", "owner": ["1000"]]
Map detailData = ["object_detail1__c": [["name": "Zhang San 1"]]]
def (Boolean error, Map data, String errorMessage) = Fx.object.create(
"object_1yO4J__c",
masterData,
detailData,
CreateAttribute.builder().build()
)batchCreate
Batch create data, with a maximum of 500 rows per batch.
Fx.object.batchCreate(String apiName, List objects, CreateAttribute attribute)
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
apiName | String | Yes | Object API Name |
objects | List[Map] | Yes | Each item is one data row |
attribute | CreateAttribute | Yes | Creation control attributes |
Return:
data:List[Map]
Minimal example:
List objects = [
["name": "Customer A", "owner": ["1000"]],
["name": "Customer B", "owner": ["1000"]]
]
def (Boolean error, List<Map> data, String errorMessage) = Fx.object.batchCreate(
"AccountObj",
objects,
CreateAttribute.builder().build()
)copyByRule
Create data by mapping rule.
Fx.object.copyByRule(String sourceApiName, String sourceId, String ruleApiName, Map masterPlus, Map detailPlus)
Use cases:
- Copy A-object data into B-object data based on a mapping rule
- Add parent or child field values on top of the mapped result
Notes:
- The original text explicitly states that the created data can trigger approval flow and workflow
Minimal example:
Map masterPlus = ["field_wbYI0__c": "Extra parent value from function"]
Map detailPlus = ["object_snpWU__c": [["field_a72ov__c": "Extra detail value"]]]
def (Boolean error, Object result, String errorMessage) = Fx.object.copyByRule(
"object_pbx98__c",
"66d827e45c1ac90001ede05c",
"map_y5iy4__c",
masterPlus,
detailPlus
)Data Update
| Method | Description | Signature |
|---|---|---|
update.increment | Incremental update for one row | Fx.object.update(String apiName, String objectId, Map updateFields, UpdateAttribute attribute) |
update.edit | Parent-child overwrite update | Fx.object.update(String apiName, String objectId, Map updateFields, Map detailData, ActionAttribute actionAttribute) |
update.byQuery | Batch update by query criteria | Fx.object.update(String apiName, QueryTemplate template, Map updateFields, UpdateAttribute attribute) |
batchUpdate | Low-level batch field update | Fx.object.batchUpdate(String apiName, Map objects, List fields, BatchUpdateAttribute attribute) |
editTeamMember | Overwrite internal related team members | Fx.object.editTeamMember(String apiName, String dataId, List teamMembers, Boolean ignoreSendingRemind) |
update.increment
Incrementally update one row.
Fx.object.update(String apiName, String objectId, Map updateFields, UpdateAttribute attribute)
Characteristics:
- Does not validate lock state
- Does not trigger pre-edit validation, post actions, or validation rules
- Better suited to focused field-level updates
Notes:
- Does not support directly updating owner, formula fields, aggregate fields, and similar fields
- Currency and exchange-rate fields cannot be set to empty
Minimal example:
Map updateFields = ["name": "New Name"]
def (Boolean error, Map data, String errorMessage) = Fx.object.update(
"object_s82CA__c",
"64b1113e87ec1c0001bfc102",
updateFields,
UpdateAttribute.builder().triggerWorkflow(true).build()
)update.edit
Overwrite parent and child data together.
Fx.object.update(String apiName, String objectId, Map updateFields, Map detailData, ActionAttribute actionAttribute)
Characteristics:
- Suitable for full parent-child rewrite
- Passing an empty collection for
detailDataclears child data - Passing
nullfordetailDatameans child data is not updated
Notes:
- Locked data cannot be updated through this method
- If locked data must be changed, evaluate
update.incrementfirst
Minimal example:
Map updateFields = ["name": "Parent Object Name"]
Map detailData = [
"object_detail__c": [
["name": "Detail 1"],
["name": "Detail 2"]
]
]
def (Boolean error, Map data, String errorMessage) = Fx.object.update(
"object_qs2nb__c",
"607d5e3dd02b9f00016507d8",
updateFields,
detailData,
ActionAttribute.create()
)update.byQuery
Batch update by query criteria.
Fx.object.update(String apiName, QueryTemplate template, Map updateFields, UpdateAttribute attribute)
Characteristics:
- Updates up to 1000 rows by default
- Set
isAllUpdate=trueif more than 1000 rows must be updated
Notes:
- Marked as a gray-release capability in the original text
- Large updates are expensive; the original text says about 3 minutes for 1000 rows
- If parameters such as
runBusiness=falseare used to bypass business logic, evaluate carefully
Minimal example:
QueryTemplate query = QueryTemplate.AND([
"name": QueryOperator.EQ("Master-detail create 1")
])
def (Boolean error, Object result, String errorMessage) = Fx.object.update(
"object_1yO4J__c",
query,
["field__c": "test"],
UpdateAttribute.builder().build()
)batchUpdate
Batch update specific fields.
Fx.object.batchUpdate(String apiName, Map objects, List fields, BatchUpdateAttribute attribute)
Parameter notes:
- In
objects, the key is the data ID and the value is the field-value map fieldsdefines the actual write scope for this call
High-risk notes:
- The original text states that this is a low-level API close to direct database updates
- If a field appears in
fieldsbut no value is provided inobjects, the field is cleared - Not recommended for calculated, aggregate, or reference fields
- Custom objects support at most 500 rows per batch
Recommendations:
- For built-in objects, evaluate
convert2SingleOperation=truefirst - When the data volume is small, looping through
update.incrementis easier to control
Minimal example:
Map objects = [
"60acc4a2d040a70001886739": ["field_bVch6__c": "test1"],
"60acc482d040a70001886582": ["field_bVch6__c": "test2"]
]
List fields = ["field_bVch6__c"]
def (Boolean error, List result, String errorMessage) = Fx.object.batchUpdate(
"object_8N0H2__c",
objects,
fields,
BatchUpdateAttribute.builder().build()
)editTeamMember
Overwrite internal related-team members.
Fx.object.editTeamMember(String apiName, String dataId, List teamMembers, Boolean ignoreSendingRemind)
Team member structure:
| Field | Type | Description |
|---|---|---|
userId | String | Team member ID |
permission | Integer | 1 read-only, 2 read-write |
role | Integer | Related team role |
type | Integer | Member type |
Notes:
- Only internal related teams can be modified
- The original role enum text and sample values are not fully consistent. Use actual runtime definitions from the system
Minimal example:
List teamMembers = [
["userId": "1058", "role": 4, "permission": 1],
["userId": "1057", "role": 4, "permission": 2]
]
def result = Fx.object.editTeamMember(
"AccountObj",
"36fd270a986842529445bf3d252cca9b",
teamMembers,
false
).result() as MapData Deletion
| Method | Description | Signature |
|---|---|---|
directDelete | Direct database delete, irreversible | Fx.object.directDelete(String apiName, String dataId) |
batchDelete | Batch direct delete | Fx.object.batchDelete(String apiName, List objectIds) |
deleteTeamMember | Delete team members | Fx.object.deleteTeamMember(String apiName, List objectIds, List teamMembers, List outTeamMemberEmployee, Boolean ignoreSendingRemind) |
bulkDelete | Batch permanent delete for invalidated data | Fx.object.bulkDelete(String apiName, List objectIds) |
delete | Permanently delete one invalidated row | Fx.object.delete(String apiName, String objectId) |
directDelete
Directly delete database data. This action is irreversible.
Fx.object.directDelete(String apiName, String dataId)
This is one of the most dangerous APIs in the document and should only be used for confirmed low-level cleanup.
Minimal example:
Fx.object.directDelete("object_kFc8w__c", "664dd6c2f7239000076e133f").result()batchDelete
Batch direct delete.
Fx.object.batchDelete(String apiName, List objectIds)
Notes:
- It does not distinguish whether the object has already been invalidated
- The data is permanently deleted directly
Minimal example:
Fx.object.batchDelete(
"object_kFc8w__c",
["664dd6c2f7239000076e133f", "664dd6c2f7239000076e1340"]
).result()deleteTeamMember
Delete related team members.
Fx.object.deleteTeamMember(String apiName, List objectIds, List teamMembers, List outTeamMemberEmployee, Boolean ignoreSendingRemind)
External team member structure:
| Field | Type | Description |
|---|---|---|
userId | String | Downstream-tenant user ID |
outTenantId | String | Downstream tenant ID |
Minimal example:
List objectIds = ["36fd270a986842529445bf3d252cca9b"]
List teamMembers = ["1058"]
List outTeamMemberEmployee = [["userId": "309175511", "outTenantId": "301185430"]]
Fx.object.deleteTeamMember(
"AccountObj",
objectIds,
teamMembers,
outTeamMemberEmployee,
false
).result()bulkDelete
Batch permanently delete invalidated data.
Fx.object.bulkDelete(String apiName, List objectIds)
Notes:
- Used only for invalidated data already in the recycle bin
- The original text recommends no more than 20 rows per call
Minimal example:
Fx.object.bulkDelete("object_c6584__c", ["6707d19a8b6d28000716bb05"]).result()delete
Permanently delete one invalidated row.
Fx.object.delete(String apiName, String objectId)
Minimal example:
Fx.object.delete("object_c6584__c", "6707d19a8b6d28000716bb05").result()Data Query
| Method | Description | Signature |
|---|---|---|
find | FQL query for multiple rows | Fx.object.find(String apiName, FQLAttribute fqlAttribute, SelectAttribute selectAttribute) |
findOne | FQL query for one row | Fx.object.findOne(String apiName, FQLAttribute fqlAttribute, SelectAttribute selectAttribute) |
findById | Query one row by ID | Fx.object.findById(String apiName, String id, FQLAttribute fqlAttribute, SelectAttribute selectAttribute) |
findByIds | Query by ID list | Fx.object.findByIds(String apiName, List ids, FQLAttribute fqlAttribute, SelectAttribute selectAttribute) |
select.query | SQL query | Fx.object.select(String sql, SelectAttribute selectAttribute) |
select.stream | Large-volume SQL streaming pagination query | Fx.object.select(String sql, SelectAttribute selectAttribute, Closure consumer) |
findWithRelated | Joined query through lookup or parent-child relation | Fx.object.findWithRelated(String apiName, String relatedField, List criteria, Map orderBy, Integer limit, Integer skip, ActionAttribute attribute) |
getTeamMember | Get team members | Fx.object.getTeamMember(String apiName, String dataId) |
find
FQL query for multiple rows.
Fx.object.find(String apiName, FQLAttribute fqlAttribute, SelectAttribute selectAttribute)
Key return fields:
| Field | Type | Description |
|---|---|---|
size | Integer | Number of rows returned in this call |
total | Integer | Total row count |
dataList | List | Data list |
Minimal example:
FQLAttribute fql = FQLAttribute.builder()
.columns(["_id", "name"])
.queryTemplate(QueryTemplate.AND(["name": QueryOperator.EQ("account1")]))
.build()
SelectAttribute selectAttribute = SelectAttribute.builder().needInvalid(false).build()
def (Boolean error, QueryResult queryResult, String errorMessage) = Fx.object.find(
"AccountObj",
fql,
selectAttribute
)findOne
FQL query for one row.
Fx.object.findOne(String apiName, FQLAttribute fqlAttribute, SelectAttribute selectAttribute)
Recommendation:
- For single-row queries, prefer this API rather than
find + limit 1
Minimal example:
FQLAttribute fql = FQLAttribute.builder()
.columns(["_id", "name"])
.queryTemplate(QueryTemplate.AND(["_id": QueryOperator.EQ("6177cde7a0cb410001930ad0")]))
.build()
def (Boolean error, Map data, String errorMessage) = Fx.object.findOne(
"AccountObj",
fql,
SelectAttribute.builder().build()
)findById
Query one row by ID.
Fx.object.findById(String apiName, String id, FQLAttribute fqlAttribute, SelectAttribute selectAttribute)
Minimal example:
FQLAttribute fql = FQLAttribute.builder()
.columns(["_id", "name"])
.build()
def (Boolean error, Map data, String errorMessage) = Fx.object.findById(
"AccountObj",
"6177cde7a0cb410001930ad0",
fql,
SelectAttribute.builder().build()
)findByIds
Query by ID list.
Fx.object.findByIds(String apiName, List ids, FQLAttribute fqlAttribute, SelectAttribute selectAttribute)
Minimal example:
FQLAttribute fql = FQLAttribute.builder()
.columns(["_id", "name"])
.build()
def (Boolean error, QueryResult result, String errorMessage) = Fx.object.findByIds(
"AccountObj",
["6177cde7a0cb410001930ad0", "6177cde7a0cb410001930ad1"],
fql,
SelectAttribute.builder().build()
)select.query
SQL query.
Fx.object.select(String sql, SelectAttribute selectAttribute)
Notes:
- The original text says
selectAttributeis optional, while the summary marks it as required. This document treats it as optional. - The returned result may be
QueryResultor an aggregateList
Minimal example:
String sql = "select _id, name from AccountObj where create_time > 0 limit 10 offset 0"
SelectAttribute attribute = SelectAttribute.builder().needInvalid(false).build()
def result = Fx.object.select(sql, attribute).result() as QueryResultselect.stream
Large-volume SQL streaming pagination query.
Fx.object.select(String sql, SelectAttribute selectAttribute, Closure consumer)
Use cases:
- Full-data scan
- Process data while querying
Limitations:
order byis not supportedlimitis not supported
Minimal example:
String sql = "select _id, name from object_227xW__c where field_rzv5M__c > 100"
Fx.object.select(sql, SelectAttribute.builder().build(), { list ->
list.each { row ->
log.info((row as Map)["name"])
}
}).result()findWithRelated
Run a joined query through lookup or parent-child relation.
Fx.object.findWithRelated(String apiName, String relatedField, List criteria, Map orderBy, Integer limit, Integer skip, ActionAttribute attribute)
Notes:
- For lookup scenarios,
apiNameis the related object API Name andrelatedFieldis the lookup field - For parent-child scenarios,
apiNameis the child object API Name andrelatedFieldis the parent-child relation field
Minimal example:
def attribute = ActionAttribute.build {
forceQueryFromDB = false
}
def (Boolean error, QueryResult result, String errorMessage) = Fx.object.findWithRelated(
"object_0uyAd__c",
"field_YjJ6d__c",
[["_id": "60868215965b1900014c0d35"]],
["create_time": 1],
10,
0,
attribute
)getTeamMember
Get team-member information.
Fx.object.getTeamMember(String apiName, String dataId)
Key returned fields:
teamMemberEmployeeteamMemberRoleteamMemberPermissionTypeteamMemberTypeoutTenantIdteamMemberName
Minimal example:
def rst = Fx.object.getTeamMember("AccountObj", "83cf73d957924284a96e9c44ebb333ec").result() as ListData Validation
| Method | Description | Signature |
|---|---|---|
duplicateSearch | Get duplicate-check result | Fx.object.duplicateSearch(String apiName, String type, Map data, String relatedApiName, Integer pageNumber, Integer pageSize) |
duplicateSearch
Get duplicate-check result.
Fx.object.duplicateSearch(String apiName, String type, Map data, String relatedApiName, Integer pageNumber, Integer pageSize)
Common type values:
NEWTOOL
Key result fields:
dataListmatchTypekeepSave
Minimal example:
Map data = ["object_describe_api_name": "object_zPSCw__c", "field_619D3__c": "123"]
def (Boolean error, Map result, String errorMessage) = Fx.object.duplicateSearch(
"object_zPSCw__c",
"NEW",
data,
null,
1,
20
)Team Member Management
| Method | Description | Signature |
|---|---|---|
replaceOutTeamMember | Fully replace external members | Fx.object.replaceOutTeamMember(String apiName, String objectId, Object outTeamMembers, Boolean ignoreSendingRemind) |
addTeamMember | Add internal team member | Fx.object.addTeamMember(String apiName, String objectId, Object teamMemberAttribute) |
addOutTeamMember | Add external team member | Fx.object.addOutTeamMember(String apiName, String objectId, Object outTeamMemberAttribute) |
changeOwner | Change owner for one row | Fx.object.changeOwner(String apiName, String dataId, String ownerId, ActionAttribute attribute) |
batchChangeOwner | Batch change owner | Fx.object.batchChangeOwner(String apiName, List changeData, ActionAttribute attribute) |
replaceOutTeamMember
Replace all external members in full.
Fx.object.replaceOutTeamMember(String apiName, String objectId, Object outTeamMembers, Boolean ignoreSendingRemind)
Notes:
- External owner cannot be replaced
Minimal example:
def member = TeamMemberEmployee.builder()
.userId("309175511")
.outTenantId("301185430")
.build()
def outMembers = OutTeamMemberAttribute.createEmployMember(
[member],
TeamMemberEnum.Permission.READANDWRITE
)
def result = Fx.object.replaceOutTeamMember(
"object_qep6N__c",
"61848edfd9007e00019ee222",
[outMembers],
false
)addTeamMember
Add internal team members.
Fx.object.addTeamMember(String apiName, String objectId, Object teamMemberAttribute)
Supported member types:
- User
- User group
- Department
- Role
Notes:
- Owner cannot be added
- If the member already exists, the existing member info is updated
Minimal example:
def teamMember = TeamMemberAttribute.createEmployMember(
["1027"],
TeamMemberEnum.Role.NORMAL_STAFF,
TeamMemberEnum.Permission.READONLY
)
Fx.object.addTeamMember("object_qep6N__c", "61848edfd9007e00019ee222", teamMember).result()addOutTeamMember
Add external team members.
Fx.object.addOutTeamMember(String apiName, String objectId, Object outTeamMemberAttribute)
Supported member types:
- External user
- Downstream tenant
- External role
- Downstream tenant group
Minimal example:
def member = TeamMemberEmployee.builder()
.userId("309175511")
.outTenantId("301185430")
.build()
def teamMember = OutTeamMemberAttribute.createEmployMember(
[member],
TeamMemberEnum.Permission.READANDWRITE
)
Fx.object.addOutTeamMember("object_qep6N__c", "61848edfd9007e00019ee222", teamMember).result()changeOwner
Change owner for one row.
Fx.object.changeOwner(String apiName, String dataId, String ownerId, ActionAttribute attribute)
Minimal example:
Fx.object.changeOwner(
"AccountObj",
"ed47841898054749a2ec9be9e6e5d728",
"1001",
ActionAttribute.create()
).result()batchChangeOwner
Batch change owner.
Fx.object.batchChangeOwner(String apiName, List changeData, ActionAttribute attribute)
Notes:
- The original signature says
changeDatausesdataId/userId - The original example uses
objectId/ownerId - Use the actual runtime definition from the test environment before production rollout
Minimal example:
List changeData = [
["objectId": "5f86b47b1bdac00001f2c300", "ownerId": ["-10000"]],
["objectId": "5f86b4a71bdac00001f2d232", "ownerId": ["-10000"]]
]
Fx.object.batchChangeOwner("object_i66LR__c", changeData, ActionAttribute.create()).result()Data Locking
| Method | Description | Signature |
|---|---|---|
lock | Lock data | Fx.object.lock(String apiName, String dataId, Boolean cascadeDetail) |
unlock | Unlock data | Fx.object.unlock(String apiName, String dataId, Boolean cascadeDetail) |
batchLock | Batch lock | Fx.object.batchLock(String apiName, List objectIds, Boolean cascadeDetail) |
batchUnlock | Batch unlock | Fx.object.batchUnlock(String apiName, List objectIds, Boolean cascadeDetail) |
lock
Lock data.
Fx.object.lock(String apiName, String dataId, Boolean cascadeDetail)
Minimal example:
Fx.object.lock("AccountObj", "e6a338ae8a944cdfb2bae737db1aa12f", true).result()unlock
Unlock data.
Fx.object.unlock(String apiName, String dataId, Boolean cascadeDetail)
Minimal example:
Fx.object.unlock("AccountObj", "e6a338ae8a944cdfb2bae737db1aa12f", true).result()batchLock
Batch lock data.
Fx.object.batchLock(String apiName, List objectIds, Boolean cascadeDetail)
Minimal example:
Fx.object.batchLock("AccountObj", ["e6a338ae8a944cdfb2bae737db1aa12f"], true).result()batchUnlock
Batch unlock data.
Fx.object.batchUnlock(String apiName, List objectIds, Boolean cascadeDetail)
Minimal example:
Fx.object.batchUnlock("AccountObj", ["e6a338ae8a944cdfb2bae737db1aa12f"], true).result()Data Invalidation and Recovery
| Method | Description | Signature |
|---|---|---|
remove | Invalidate one row | Fx.object.remove(String apiName, String id) |
batchRemove | Batch invalidate | Fx.object.batchRemove(String apiName, List objectIds, RemoveAttribute attribute) |
bulkRecover | Batch recover invalidated data | Fx.object.bulkRecover(String apiName, List objectIds) |
remove
Invalidate one row and move it to the recycle bin.
Fx.object.remove(String apiName, String id)
Minimal example:
def rst = Fx.object.remove("AccountObj", "ed47841898054749a2ec9be9e6e5d728").result() as MapbatchRemove
Batch invalidate business data.
Fx.object.batchRemove(String apiName, List objectIds, RemoveAttribute attribute)
Notes:
- Only rows in normal lifecycle status can be invalidated
- The original text marks
attributeas optional in one place but required in another. This document recommends always passing it
Minimal example:
RemoveAttribute attribute = RemoveAttribute.builder()
.triggerApprovalFlow(false)
.triggerWorkflow(false)
.skipFunctionAction(true)
.build()
def (Boolean error, Object data, String errorMessage) = Fx.object.batchRemove(
"object_kFc8w__c",
["664dd6c2f7239000076e133f"],
attribute
)bulkRecover
Batch recover invalidated data.
Fx.object.bulkRecover(String apiName, List objectIds)
Notes:
- The original text recommends no more than 20 rows per call
Minimal example:
def rst = Fx.object.bulkRecover("object_c6584__c", ["6707d19a8b6d28000716bb05"]).result() as MapData Aggregation
| Method | Description | Signature |
|---|---|---|
aggregate.groupBy | Group by field and aggregate | Fx.object.aggregate(String apiName, Aggregate type, List criteria, String groupByField, FindAttribute attribute) |
aggregate.simple | Conditional aggregation | Fx.object.aggregate(String apiName, Aggregate type, Integer decimalScale, List criteria, FindAttribute attribute) |
aggregate.groupBy
Group by field and aggregate.
Fx.object.aggregate(String apiName, Aggregate type, List criteria, String groupByField, FindAttribute attribute)
Typical use case:
- Group by one field and compute
SUM/COUNT/MAX/MIN/AVG
Minimal example:
def (Boolean error, List data, String errorMessage) = Fx.object.aggregate(
"object_227xW__c",
Aggregate.MAX("field_rzv5M__c"),
[["field_rzv5M__c": Operator.GT(10)]],
"field_qC2yp__c",
FindAttribute.getDefaultFindAttribute()
)aggregate.simple
Aggregate by criteria.
Fx.object.aggregate(String apiName, Aggregate type, Integer decimalScale, List criteria, FindAttribute attribute)
Notes:
- The original text incorrectly described
decimalScaleas an object API name; this version normalizes it to decimal precision
Cautions:
- Aggregation uses ES by default
- If strong consistency matters, prefer
forceQueryFromDB=true
Minimal example:
def (Boolean error, Object result, String errorMessage) = Fx.object.aggregate(
"object_m4S5S__c",
Aggregate.AVG("field_k2y2d__c"),
2,
[["field_Oo1K2__c": Operator.GT("200")]],
FindAttribute.getDefaultFindAttribute()
)Object Metadata Query
| Method | Description | Signature |
|---|---|---|
getOptionName | Get option label by value | Fx.object.getOptionName(String objectApiName, String fieldApiName, String value) |
findDescribe | Query object description | Fx.object.findDescribe(String apiName) |
getOptionInfo | Get single-select/multi-select/business-type value mapping | Fx.object.getOptionInfo(String apiName, String fieldApiName) |
getMappingRule | Get mapping-rule description | Fx.object.getMappingRule(String mappingRuleApiName) |
getCascadeOption | Get single-select cascade configuration | Fx.object.getCascadeOption(String apiName, String fieldApiName, String optionValue) |
getCascadeOption.attribute | Get single-select cascade configuration by attribute object | Fx.object.getCascadeOption(OptionAttribute optionAttribute) |
getOptionName
Get the label of a single-select, multi-select, or business-type value.
Fx.object.getOptionName(String objectApiName, String fieldApiName, String value)
Notes:
- The original text used
filedAPIName; this document normalizes it tofieldApiName
Minimal example:
def (Boolean error, Object data, String errorMessage) = Fx.object.getOptionName(
"object_kFc8w__c",
"mc_currency",
"CNY"
)findDescribe
Query object description data such as fields and option definitions.
Fx.object.findDescribe(String apiName)
Notes:
- The original summary showed no parameters
- The body example actually passed an object API Name
- This document normalizes the signature to require
apiName
Minimal example:
def rst = Fx.object.findDescribe("object_qep6N__c").result() as MapgetOptionInfo
Query mappings for single-select, multi-select, and business-type values.
Fx.object.getOptionInfo(String apiName, String fieldApiName)
Return characteristics:
- Provides both
label -> valueandvalue -> labelmappings
Minimal example:
def rst = Fx.object.getOptionInfo("EnterpriseInfoObj", "enterprise_type").result() as MapgetMappingRule
Query mapping-rule metadata.
Fx.object.getMappingRule(String mappingRuleApiName)
Key return fields:
ruleListsourceApiNametargetApiNamefieldMapping
Minimal example:
def rst = Fx.object.getMappingRule("map_ri5oc__c").result() as MapgetCascadeOption
Get single-select cascade configuration.
Preferred style 1:
Fx.object.getCascadeOption(String apiName, String fieldApiName, String optionValue)
Preferred style 2:
Fx.object.getCascadeOption(OptionAttribute optionAttribute)
Notes:
- The original signatures and examples are inconsistent
- This document keeps both styles, and the
OptionAttributestyle matches the legacy example
Minimal example:
def optionAttribute = OptionAttribute.builder()
.apiName("object_qep6N__c")
.fieldApiName("field_16Yl4__c")
.optionValue("C3mG8ou09")
.build()
def rst = Fx.object.getCascadeOption(optionAttribute).result() as MapOther Functions
| Method | Description | Signature |
|---|---|---|
merge | Merge accounts or leads | Fx.object.merge(String apiName, String targetDataId, List sourceDataIds, Map objectData) |
merge
Object merge. Currently only account and lead objects are supported.
Fx.object.merge(String apiName, String targetDataId, List sourceDataIds, Map objectData)
Notes:
- The original summary showed no parameters
- The original example clearly passed four parameters
- This document normalizes the signature to four parameters
Minimal example:
Map objectData = ["name": "Merge Test 10", "mobile": "1884***4501"]
Fx.object.merge(
"LeadsObj",
"61b9aed9a3c69e0001351a87",
["61b9af07a3c69e000135213f"],
objectData
).result()Reference Types
CreateAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| calculateDefaultValue | boolean | Whether to calculate default values, default is false |
| fillOutOwner | boolean | Whether to populate external owner (used by business logic interfaces, not by metadata interfaces), default is false |
| designatedCreatedBy | boolean | Whether to specify creator (including all subordinate objects). Default is system. Can be specified in objectData parameter with key: created_by (List<String>) by passing personnel IDs |
| specifyTime | boolean | Whether to specify creation time (typically uses current time), default is false |
| skipAfterFunction | boolean | Whether to skip post-action functions (used by business logic interfaces, not by metadata interfaces), default is false |
| triggerWorkflow | boolean | Whether to trigger workflow, default is true |
| duplicateSearch | boolean | Whether to perform duplicate check (not used by metadata interfaces as metadata layer implements duplicate check), default is true |
| enableRealTimeCalculateDataAuth | boolean | Whether to enable real-time data permission calculation, default is false |
| skipFunctionAction | boolean | Whether to skip pre-validation functions, default is false |
| forceQueryFromDB | boolean | Whether to force query from database (aligned with legacy interfaces, currently no distinction) |
| triggerApprovalFlow | boolean | Whether to trigger approval flow, default is true |
Minimal Example
CreateAttribute attr = CreateAttribute.builder()
.triggerWorkflow(true)
.duplicateSearch(true)
.build()UpdateAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| isAllUpdate | boolean | Whether to update all data. When false, a maximum of 1000 records will be updated; when true, there is no quantity limit. Default is false. |
| triggerWorkflow | boolean | Whether to trigger workflow. Default is true. Approval workflows are not supported. |
| duplicateSearch | boolean | Whether to perform duplicate check. Default is true. |
| modifiedBySelf | boolean | Whether to designate the current user as the modifier. Default is false (system update, updated by system). When set to true, the current user performs the update (updated by current user). Note: Update may fail due to insufficient data permissions. Not all scenarios can retrieve the current user, in which case system update will be used by default. |
| skipImmutableFieldValidate | boolean | Whether to skip immutable field validation. Default is false. Primarily used when synchronizing data from upstream to downstream to determine if locked fields can be edited downstream. |
| applyDataPrivilegeCheck | boolean | Whether to perform data privilege validation. Default is false (no validation). |
Minimal Example
UpdateAttribute attr = UpdateAttribute.builder()
.triggerWorkflow(true)
.isAllUpdate(false)
.build()ActionAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| fillOutOwner | boolean | Whether to populate external responsible person, default is false |
| designatedCreatedBy | boolean | Whether to specify creator (including all subordinate objects as designated creators), default is system. Can be specified in objectData parameter via key: created_by (List<String>) by passing personnel IDs to set creator |
| specifyTime | boolean | Specify creation time (only for create interface), default is false |
| skipAfterFunction | boolean | Controls whether to skip post-action functions during create/update operations, default is false |
| triggerWorkflow | boolean | Whether to trigger workflow, default is true |
| duplicateSearch | boolean | Whether to perform duplicate check, default is true |
| modifiedBySelf | boolean | Whether to designate current user as modifier (only for update interface). Default false means system update (modified by system); true means current user update. Note: May fail due to insufficient data permissions; falls back to system when current user cannot be obtained |
| skipFunctionAction | boolean | For create/update: controls skipping pre-validation functions only. For bulkRemove/changeOwner/batchChangeOwner: controls skipping both pre and post functions |
| skipImmutableFieldValidate | boolean | Whether to skip immutable field validation (default false). Mainly used when synchronizing data from upstream to downstream to determine if locked fields can be edited |
| forceQueryFromDB | boolean | Whether to force query from database, default is false |
| triggerApprovalFlow | boolean | Whether to trigger approval flow, default is true |
Quick Methods
ActionAttribute.create()- Quick construction method with all properties set to default values.ActionAttribute.build { ... }- Builder construction properties, assigning values within the closure.
Minimal Example
// Use builder
ActionAttribute attr = ActionAttribute.builder()
.triggerWorkflow(true)
.forceQueryFromDB(false)
.build()
// Use quick method create
ActionAttribute attr2 = ActionAttribute.create()
// Use build closure
ActionAttribute.build {
forceQueryFromDB = false
}RemoveAttribute
| Parameter Name | object | Description |
|---|---|---|
| triggerWorkflow | java.lang.Boolean | Whether to trigger the workflow (default: triggered) |
| useCurrentIdentity | java.lang.Boolean | Whether to query data using the current user identity (default: false, uses system) |
| skipFunctionAction | java.lang.Boolean | Whether to skip pre/post action functions (currently no distinction between pre/post actions) |
| skipButtonConditions | java.lang.Boolean | Skip button display condition validation |
| triggerApprovalFlow | java.lang.Boolean | Whether to trigger the approval flow (default: triggered) |
Minimal Example:
RemoveAttribute attr = RemoveAttribute.builder()
.triggerWorkflow(false)
.skipFunctionAction(true)
.build()BatchUpdateAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| triggerWorkflow | boolean | Whether to trigger workflow. Defaults to true. |
| convert2SingleOperation | boolean | Preconfigured objects contain special business logic that doesn't support batch updates. Setting convert2SingleOperation to true will convert the operation to single-item updates in a loop (slower performance). Defaults to false (no conversion to single updates). Only applicable to preconfigured objects. |
Minimal Example
BatchUpdateAttribute attr = BatchUpdateAttribute.builder()
.triggerWorkflow(true)
.convert2SingleOperation(true)
.build()FindAttribute
| Field | Type | Description |
|---|---|---|
returnRelatedValue | Boolean | Whether to return related values |
extendFieldApiNames | List[String] | Fields that need __r extension |
forceQueryFromDB | Boolean | Whether to query from DB |
Minimal Example:
// Use default configuration
FindAttribute attr = FindAttribute.getDefaultFindAttribute()
// Custom configuration
FindAttribute attr = FindAttribute.builder()
.forceQueryFromDB(true)
.returnRelatedValue(true)
.build()SelectAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| needRelevantTeam | java.lang.Boolean | Whether relevant teams are required, default is false |
| needQuote | java.lang.Boolean | Whether to calculate referenced fields in real-time, default is true |
| paginationOptimization | java.lang.Boolean | Whether to perform pagination optimization, default is false. Can be set to true when handling large-scale paginated data operations |
| fillExtendInfo | java.lang.Boolean | Whether to automatically populate __r fields (e.g. personnel information), default is false |
| needCount | java.lang.Boolean | Whether to return the total count of matching records, default is false |
| validateFilterField | java.lang.Boolean | Whether to validate filter fields. Before 7/6, default is false (can be manually set to true). After 7/6, default is true (setting to false will not take effect) |
| calculateCount | java.lang.Boolean | Whether to calculate statistical fields in real-time, default is true |
| searchRichTextExtra | java.lang.Boolean | Whether to return complete rich text/collaborative rich text/long text content, default is false |
| filterByDataRight | java.lang.Boolean | Whether to filter data based on data permissions (default is false) |
| needCalculate | java.lang.Boolean | Whether to execute calculated fields during query, default is true |
| needInvalid | java.lang.Boolean | Whether to return invalidated data, default is false |
| convertQuoteForView | java.lang.Boolean | Whether to return referenced fields in display format (default is false). This parameter mainly applies to single-select, multi-select, boolean and business-type fields. By default returns value; when set to true, returns label with value in ${fieldApiName}__v and other options in ${fieldApiName}__o |
| needOptionLabel | java.lang.Boolean | Whether to return option labels, default is false. When true, single-select/multi-select labels will be populated in ${fieldApiName}__r |
Minimal Example
SelectAttribute attr = SelectAttribute.builder()
.needInvalid(false)
.needCalculate(true)
.needCount(true)
.build()FQLAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| queryTemplate | com.fxiaoke.functions.model.QueryTemplate | WHERE [query conditions], refer to QueryTemplate documentation for details |
| columns | java.util.List[java.lang.String] | SELECT [fields] |
| limit | java.lang.Integer | LIMIT [query count] Default: 10, Maximum: 100 |
| orderBy | java.util.Map | ORDER BY [sort fields] Example: ["_id":1] 1 for ascending, -1 for descending |
| skip | java.lang.Integer | SKIP [pagination offset] |
Minimal Example
FQLAttribute fql = FQLAttribute.builder()
.queryTemplate(QueryTemplate.AND(["name": QueryOperator.LIKE("%test%")]))
.columns(["_id", "name", "owner"])
.limit(20)
.orderBy(["create_time": -1])
.skip(0)
.build()OptionAttribute
Field description
| Parameter Name | object | Description |
|---|---|---|
| apiName | java.lang.String | Object API name |
| optionValue | java.lang.String | Parent radio option value |
| fieldApiName | java.lang.String | Parent radio field API name |
Minimal Example
OptionAttribute attr = OptionAttribute.builder()
.apiName("object_qep6N__c")
.optionValue("option_id")
.fieldApiName("field_16Yl4__c")
.build()TeamMemberAttribute
1. createEmployMember Add Internal Member
Add internal members
TeamMemberAttribute.createEmployMember()
Code examples
def employTeamMember = TeamMemberAttribute.createEmployMember(["1027"], TeamMemberEnum.Role.NORMAL_STAFF, TeamMemberEnum.Permission.READONLY)
//employTeamMember.setIgnoreSendingRemind(true) // Optional parameter: whether to ignore sending CRM reminders. Default is false
//employTeamMember.setRealtime(true) // Optional parameter: whether to take effect in real-time. Default is false
def employTeamResult = Fx.object.addTeamMember("object_qep6N__c","61848edfd9007e00019ee222", employTeamMember)
log.info(employTeamResult)2. createGroupMember Add group member
Add group members
TeamMemberAttribute.createGroupMember()
Code examples
def groupTeamMember = TeamMemberAttribute.createGroupMember(["6152bd0de3e51c0001ec4de3"], TeamMemberEnum.Role.NORMAL_STAFF, TeamMemberEnum.Permission.READANDWRITE)
//groupTeamMember.setIgnoreSendingRemind(true) // Optional parameter: whether to ignore sending CRM reminders. Default is false
//groupTeamMember.setRealtime(true) // Optional parameter: whether to take effect immediately. Default is false
def groupTeamResult = Fx.object.addTeamMember("object_qep6N__c","61848edfd9007e00019ee222", groupTeamMember)
log.info(groupTeamResult)3. createDepartmentMember Add department member
Add department members
TeamMemberAttribute.createDepartmentMember()
Code examples
def deptTeamMember = TeamMemberAttribute.createDepartmentMember(["1008"], TeamMemberEnum.Role.NORMAL_STAFF, TeamMemberEnum.Permission.READONLY)
//deptTeamMember.setIgnoreSendingRemind(true) // Optional parameter: whether to ignore sending CRM reminders. Default is false
//deptTeamMember.setRealtime(true) // Optional parameter: whether to take effect in real time. Default is false
def deptTeamResult = Fx.object.addTeamMember("object_qep6N__c","61848edfd9007e00019ee222", deptTeamMember)
log.info(deptTeamResult)4. createRoleMember Add Role Member
Add Role Members
TeamMemberAttribute.createRoleMember()
Code examples
def roleTeamMember = TeamMemberAttribute.createRoleMember(["00000000000000000000000000000009"], TeamMemberEnum.Role.NORMAL_STAFF, TeamMemberEnum.Permission.READONLY)
//roleTeamMember.setIgnoreSendingRemind(true) // Optional parameter: whether to ignore sending CRM reminders. Default is false
//roleTeamMember.setRealtime(true) // Optional parameter: whether to take effect in real-time. Default is false
def roleTeamResult = Fx.object.addTeamMember("object_qep6N__c","61848edfd9007e00019ee222", roleTeamMember)
log.info(roleTeamResult)OutTeamMemberAttribute
1. createEmployMember Add External Member
Add External Members
OutTeamMemberAttribute.createEmployMember(<List teamMemberList>, <Permission permission>)
Request parameters
Request Body
| Parameter Name | Type | Description | Required |
|---|---|---|---|
| teamMemberList | List[object] | External member list to be added | Y |
| permission | Permission | TeamMemberEnum.Permission.READONLY //Read-only TeamMemberEnum.Permission.READANDWRITE //Read-write TeamMemberEnum.Permission.NO_PERMISSION //No permission | Y |
Return Parameters
| Parameter Name | Type | Description |
|---|---|---|
| outTeamMemberAttribute | OutTeamMemberAttribute |
Code examples
def teamMemberEmployee = TeamMemberEmployee.builder()
.userId("309175511")
.outTenantId("301185430")
.build()
OutTeamMemberAttribute outEmployTeamMember = OutTeamMemberAttribute.createEmployMember([teamMemberEmployee], TeamMemberEnum.Permission.READANDWRITE)
def outEmployTeamResult = Fx.object.addOutTeamMember("object_qep6N__c","61848edfd9007e00019ee222", outEmployTeamMember)
log.info(outEmployTeamResult)2. createOutTenantMember Add Downstream Enterprise
Add Downstream Enterprise
OutTeamMemberAttribute.createOutTenantMember()
Code examples
def outTenant = TeamMemberEmployee.builder()
.userId("300012805")
.outTenantId("300012805")
.build()
OutTeamMemberAttribute outTenantTeamMember = OutTeamMemberAttribute.createOutTenantMember([outTenant], TeamMemberEnum.Permission.READANDWRITE)
def outTenantTeamResult = Fx.object.addOutTeamMember("object_qep6N__c","61848edfd9007e00019ee222", outTenantTeamMember)
log.info(outTenantTeamResult)3. createRoleMember Add External Role
Add External Role
OutTeamMemberAttribute.createRoleMember()
Code examples
OutTeamMemberAttribute outRoleTeamMember = OutTeamMemberAttribute.createRoleMember(["5d1f28eee4b0896efc933508"], TeamMemberEnum.Permission.READANDWRITE)
def outRoleTeamResult = Fx.object.addOutTeamMember("object_qep6N__c","61848edfd9007e00019ee222", outRoleTeamMember)
log.info(outRoleTeamResult)4. createOutTenantGroupMember Add downstream enterprise group member
Add downstream enterprise group
OutTeamMemberAttribute.createOutTenantGroupMember()
Code examples
OutTeamMemberAttribute outTenantGroupTeamMember = OutTeamMemberAttribute.createOutTenantGroupMember(["613880213ed24b000150a713"], TeamMemberEnum.Permission.READANDWRITE)
def outTenantGroupResult = Fx.object.addOutTeamMember("object_qep6N__c","61848edfd9007e00019ee222", outTenantGroupTeamMember)
log.info(outTenantGroupResult)QueryOperator
1. EQ Query data that matches the condition with equality
Query data matching the specified conditions
QueryOperator.EQ()
Code examples
List criteria = [["name": Operator.EQ("test")]]2. NE Query for data not equal to the condition
Query data that does not match the condition
QueryOperator.NE()
Code examples
List criteria = [["name": Operator.NE("Test")]]3. GT Query for Data Greater Than Condition
Query data greater than the condition
QueryOperator.GT()
Code examples
List criteria = [["create_time": Operator.GT(1645427372658)]]4. LT Query for data less than the specified condition
Query data smaller than the condition
QueryOperator.LT()
Code examples
List criteria = [["create_time": Operator.LT(1645427372658)]]5. GTE Query data that meets the greater than or equal to condition
Query data that meets the greater-than-or-equal-to condition
QueryOperator.GTE()
Code examples
List criteria = [["create_time": Operator.GTE(1645427372658)]]6. Query data with LTE (Less Than or Equal) condition in LTE
Query data with less than or equal to condition
QueryOperator.LTE()
Code examples
List criteria = [["create_time": Operator.LTE(1645427372658)]]7. LIKE fuzzy matching for string content
Fuzzy matching of string content
QueryOperator.LIKE()
Code examples
List criteria = [["name": Operator.LIKE("Yidong Fenxiang")]]8. NLIKE Excludes fuzzy string matching
Exclude fuzzy matching string content
QueryOperator.NLIKE()
Code examples
List criteria = [["name": Operator.NLIKE("Yidong Fenxiang")]]9. Querying for Intersecting Data in IN Clauses
If the data is [1,2,3] and the query condition is [1,4], the result will be returned (because of the intersection with 1).
If the data is [1,2,3] and the query condition is [4,5], no result will be returned.
Query for Intersecting Data
If the data is [1,2,3] and the query condition is [1,4], it will return (because of the intersection with 1).
If the data is [1,2,3] and the query condition is [4,5], it will not return (no intersection).
QueryOperator.IN()
Code examples
List criteria = [["name": Operator.IN(["Yidong", "Fenxiang"])]]10. Querying Non-Intersecting Data with NIN
Query non-overlapping data
QueryOperator.NIN()
Code examples
List criteria = [["name": Operator.NIN(["Yidong", "Fenxiang"])]]11. CONTAINS queries for array fields where the data matches a subset of the input conditions
For example, if the data is [1,2,3] and the query condition is [1,2], it will return the data
If the data is [1,2,3] and the query condition is [3,4], it will not return the data
Query for array fields in data that match a subset of the input conditions
For example, if the data is [1,2,3] and the query condition is [1,2], it will return the data
If the data is [1,2,3] and the query condition is [3,4], it will not return the data
QueryOperator.CONTAINS()
Code examples
List criteria = [["name": Operator.CONTAINS(["Yidong", "Fenxiang"])]]12. NCONTAINS Query for data where the array field does not contain a subset matching the input condition.
For example, if the data is [1,2,3] and the query condition is [1,2], it will not return. If the data is [1,2,3] and the query condition is [3,4], it will return.
Query for data where the array field contains elements outside the subset of input conditions.
For example:
- If the data is [1,2,3] and the query condition is [1,2], no results will be returned.
- If the data is [1,2,3] and the query condition is [3,4], results will be returned.
QueryOperator.NCONTAINS()
Code examples
List criteria = [["name": Operator.NCONTAINS(["Yidong", "Fenxiang"])]]13. HASANYOF Query data that matches any element in the array
Retrieve any data that matches any element in the array
QueryOperator.HASANYOF()
Code examples
List criteria = [["name": Operator.HASANYOF(["Yidong", "Fenxiang"])]]14. NHASANYOF Query data not present in the array
Query data not present in the array
QueryOperator.NHASANYOF()
Code examples
List criteria = [["name": Operator.NHASANYOF(["Yidong", "Fenxiang"])]]15. EXISTS Query for data fields with content (Yes/No)
Query whether data fields contain content (Yes/No)
QueryOperator.EXISTS()
Code examples
List criteria = [["name": Operator.EXISTS(true)]]16. STARTWITH Query data starting with...
Query data starting with...
QueryOperator.STARTWITH()
Code examples
List criteria = [["name": Operator.STARTWITH("Yidong")]]17. ENDWITH Query data ending with...
Query data ending with...
QueryOperator.ENDWITH()
Code examples
List criteria = [["name": Operator.ENDWITH("Yidong")]]18. BETWEEN Query for data within a specified range
Query data within the specified range
QueryOperator.BETWEEN()
Code examples
List criteria = [["name": Operator.BETWEEN([154542372658, 1645427372658])]]Usage Recommendations
Preferred Defaults
- Prefer
findOnefor single-row queries - Prefer
select.streamfor large-volume queries - Prefer
update.incrementfor normal field updates - Use
update.editonly for full parent-child overwrite - For built-in object batch changes, evaluate
batchUpdate.convert2SingleOperationfirst
High-Risk Interfaces
directDeletebatchDeletebulkDeletebatchUpdateupdate.byQuery
For these interfaces, always confirm:
- Whether part of the business validations are bypassed
- Whether workflow, approval flow, and pre/post actions are affected
- Whether a large data set may be impacted
- Whether execution must force DB query or use current-user permission context
Legacy Issue Fix Log
This optimized version explicitly fixes or avoids the following problems:
- Split overloaded methods such as
updateinto scenario-based sections likeupdate.increment,update.edit, andupdate.byQuery - Standardize
String/List/Map/Booleannotation instead of mixingstring/object - Resolve signature conflicts for
findDescribe,getCascadeOption, andmerge - Normalize
filedAPINametofieldApiName - Remove broken links, meaningless references, and damaged stitched examples
- Centralize high-risk APIs to make review and usage safer
Changelog
| Version | Date | Changes | Author |
|---|---|---|---|
| v1.0 | 2026-05-20 | Initial version |
Background
This document provides detailed information about the Fx.object API functionality and usage, helping developers integrate relevant capabilities.
Applicable Scenarios
Specific applicable scenarios are determined by actual business needs. Developers can select the appropriate API for integration as required.
Prerequisites
- Access to Fxiaoke Open Platform
- Application authorization and configuration completed
- Basic knowledge of relevant business domain
Steps
Please refer to the detailed instructions for each API.
Notes
- Ensure prerequisites are met before calling APIs
- Pay attention to API call frequency limits
- Refer to error code documentation for exception handling
Compatibility note: This version currently has no deprecated or compatibility notes.
