Skip to content

Commit 1abb5da

Browse files
akoclaude
andcommitted
feat: add IMPORT FROM MAPPING and EXPORT TO MAPPING microflow actions
Full read+write support for import/export mapping actions in microflows: $Pet = IMPORT FROM MAPPING Module.IMM($JsonString); $Json = EXPORT TO MAPPING Module.EMM($Pet); Import assignment is optional (persistent entities store directly to DB). Implementation: grammar rules, AST types, visitor, executor builder (auto-resolves entity type and single/list from JSON structure), BSON writer (ImportMappingCall with ResultHandling, StringExport with MappingRequestHandling), and BSON parser for DESCRIBE roundtrip. Also updates: MDL quick reference, feature matrix, help topics (rest, integration), skill doc, docs-site REST integration page, and doctype test examples with 3 executable microflows. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e99a356 commit 1abb5da

23 files changed

+9514
-8109
lines changed

.claude/skills/mendix/rest-call-from-json.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,46 @@ END;
133133

134134
---
135135

136+
## Step 5 — Import/Export Mapping in Microflows (Optional)
137+
138+
Instead of using `RETURNS MAPPING` on a REST CALL, you can use standalone import/export mapping actions. This is useful when you already have a JSON string and want to map it to entities, or when you want to serialize entities back to JSON.
139+
140+
### Import from mapping
141+
142+
Applies an import mapping to a string variable (JSON content) to produce entity objects:
143+
144+
```sql
145+
-- With assignment (non-persistent entities, need the result in the flow)
146+
$PetResponse = IMPORT FROM MAPPING Module.IMM_Pet($JsonContent);
147+
148+
-- Without assignment (persistent entities, just stores to DB)
149+
IMPORT FROM MAPPING Module.IMM_Pet($JsonContent);
150+
```
151+
152+
### Export to mapping
153+
154+
Applies an export mapping to an entity object to produce a JSON string:
155+
156+
```sql
157+
$JsonOutput = EXPORT TO MAPPING Module.EMM_Pet($PetResponse);
158+
```
159+
160+
### Complete import → process → export microflow
161+
162+
```sql
163+
CREATE MICROFLOW Module.ProcessPetData ()
164+
BEGIN
165+
DECLARE $ResponseContent String = $latestHttpResponse/Content;
166+
$PetResponse = IMPORT FROM MAPPING Module.IMM_Pet($ResponseContent);
167+
-- Process the imported data...
168+
$JsonOutput = EXPORT TO MAPPING Module.EMM_Pet($PetResponse);
169+
LOG INFO NODE 'Integration' 'Exported: ' + $JsonOutput;
170+
END;
171+
/
172+
```
173+
174+
---
175+
136176
## Complete Example — Bible Verse API
137177

138178
```sql

cmd/mxcli/help_topics/integration.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ SERVICE TYPES
1313
Published REST: SHOW PUBLISHED REST SERVICES [IN Module];
1414
Business Events: SHOW BUSINESS EVENT SERVICES [IN Module];
1515
DB Connections: SHOW DATABASE CONNECTIONS [IN Module];
16+
JSON Structures: SHOW JSON STRUCTURES [IN Module];
17+
Import Mappings: SHOW IMPORT MAPPINGS [IN Module];
18+
Export Mappings: SHOW EXPORT MAPPINGS [IN Module];
1619
External Entities: SHOW EXTERNAL ENTITIES [IN Module];
1720
External Actions: SHOW EXTERNAL ACTIONS [IN Module];
1821

cmd/mxcli/help_topics/rest.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,44 @@ DESCRIBE COMMANDS
1515
DESCRIBE REST CLIENT MyModule.PetStoreAPI; -- Full MDL definition
1616
DESCRIBE PUBLISHED REST SERVICE MyModule.MyAPI; -- Full MDL definition
1717

18+
JSON STRUCTURES & MAPPINGS
19+
--------------------------
20+
21+
SHOW JSON STRUCTURES; -- List all JSON structures
22+
DESCRIBE JSON STRUCTURE Module.JSON_Pet; -- Element tree + snippet
23+
CREATE JSON STRUCTURE Module.JSON_Pet SNIPPET '{"id": 1}';
24+
25+
SHOW IMPORT MAPPINGS; -- List import mappings
26+
DESCRIBE IMPORT MAPPING Module.IMM_Pet; -- Full CREATE statement
27+
CREATE IMPORT MAPPING Module.IMM_Pet
28+
WITH JSON STRUCTURE Module.JSON_Pet
29+
{
30+
CREATE Module.PetResponse {
31+
PetId = id,
32+
Name = name
33+
}
34+
};
35+
36+
SHOW EXPORT MAPPINGS; -- List export mappings
37+
DESCRIBE EXPORT MAPPING Module.EMM_Pet; -- Full CREATE statement
38+
CREATE EXPORT MAPPING Module.EMM_Pet
39+
WITH JSON STRUCTURE Module.JSON_Pet
40+
{
41+
Module.PetResponse {
42+
id = PetId,
43+
name = Name
44+
}
45+
};
46+
47+
MICROFLOW ACTIONS
48+
-----------------
49+
50+
-- Import from mapping (JSON string → entities)
51+
$Pet = IMPORT FROM MAPPING Module.IMM_Pet($JsonContent);
52+
53+
-- Export to mapping (entity → JSON string)
54+
$Json = EXPORT TO MAPPING Module.EMM_Pet($Pet);
55+
1856
CATALOG QUERIES
1957
---------------
2058

docs-site/src/examples/rest-integration.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,77 @@ BEGIN
105105
END;
106106
/
107107
```
108+
109+
## JSON Structure + Import Mapping
110+
111+
Map a JSON response to Mendix entities using a JSON structure and import mapping.
112+
113+
```sql
114+
-- Step 1: Define the JSON structure
115+
CREATE JSON STRUCTURE Integration.JSON_Pet
116+
SNIPPET '{"id": 1, "name": "Fido", "status": "available"}';
117+
118+
-- Step 2: Create a non-persistent entity to hold the data
119+
CREATE NON-PERSISTENT ENTITY Integration.PetResponse (
120+
PetId: Integer,
121+
Name: String,
122+
Status: String
123+
);
124+
/
125+
126+
-- Step 3: Create the import mapping
127+
CREATE IMPORT MAPPING Integration.IMM_Pet
128+
WITH JSON STRUCTURE Integration.JSON_Pet
129+
{
130+
CREATE Integration.PetResponse {
131+
PetId = id,
132+
Name = name,
133+
Status = status
134+
}
135+
};
136+
137+
-- Step 4: Use in a microflow with IMPORT FROM MAPPING
138+
-- $PetResponse = IMPORT FROM MAPPING Integration.IMM_Pet($JsonContent);
139+
```
140+
141+
## Export Mapping (Entity → JSON)
142+
143+
Serialize entities back to JSON using an export mapping.
144+
145+
```sql
146+
CREATE EXPORT MAPPING Integration.EMM_Pet
147+
WITH JSON STRUCTURE Integration.JSON_Pet
148+
{
149+
Integration.PetResponse {
150+
id = PetId,
151+
name = Name,
152+
status = Status
153+
}
154+
};
155+
156+
-- Use in a microflow with EXPORT TO MAPPING
157+
-- $JsonOutput = EXPORT TO MAPPING Integration.EMM_Pet($PetResponse);
158+
```
159+
160+
## Nested Mappings with Associations
161+
162+
Map nested JSON objects to multiple entities linked by associations.
163+
164+
```sql
165+
CREATE IMPORT MAPPING Integration.IMM_Order
166+
WITH JSON STRUCTURE Integration.JSON_Order
167+
{
168+
CREATE Integration.OrderResponse {
169+
OrderId = orderId KEY,
170+
CREATE Integration.OrderResponse_CustomerInfo/Integration.CustomerInfo = customer {
171+
Email = email,
172+
Name = name
173+
},
174+
CREATE Integration.OrderResponse_OrderItem/Integration.OrderItem = items {
175+
Sku = sku,
176+
Quantity = quantity,
177+
Price = price
178+
}
179+
}
180+
};
181+
```

docs/01-project/MDL_FEATURE_MATRIX.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ Document types that exist in Mendix but have no MDL support:
199199
| **Web service publish** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Published SOAP web services |
200200
| **Web service consume** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Consumed SOAP web services |
201201
| **Ext. DB connector** | N | N | N | N | N | N | 05 | N | N | N | N | Y | N | N | N | N | N | External database connections |
202-
| **Import mappings** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | JSON/XML import mappings |
203-
| **Export mappings** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | JSON/XML export mappings |
204-
| **JSON transformations** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | JSON structure definitions |
202+
| **Import mappings** | Y | Y | Y | N | Y | N | 06 | Y | N | N | P | Y | N | N | N | Y | N | JSON import mappings with v2 syntax |
203+
| **Export mappings** | Y | Y | Y | N | Y | N | 06 | Y | N | N | P | Y | N | N | N | Y | N | JSON export mappings with v2 syntax |
204+
| **JSON transformations** | Y | Y | Y | Y | Y | N | 20 | Y | N | N | P | N | N | N | N | N | N | JSON structure definitions |
205205
| **Message definitions** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Message definition documents |
206206
| **XML schemas** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Imported XML schema documents |
207207
| **Workflows** | Y | Y | Y | N | Y | N | N | N | Y | Y | N | N | Y | N | Y | Y | N | SHOW/DESCRIBE/CREATE/DROP/GRANT/REVOKE implemented |

docs/01-project/MDL_QUICK_REFERENCE.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ AUTHENTICATION Basic, Session
172172
| WHILE | `WHILE condition BEGIN ... END WHILE;` | Condition-based loop |
173173
| Return | `RETURN $value;` | Required at end of every flow path |
174174
| Execute DB query | `$Result = EXECUTE DATABASE QUERY Module.Conn.Query;` | 3-part name; supports DYNAMIC, params, CONNECTION override |
175+
| Import mapping | `[$Var =] IMPORT FROM MAPPING Module.IMM($SourceVar);` | Apply import mapping to string variable |
176+
| Export mapping | `$Var = EXPORT TO MAPPING Module.EMM($EntityVar);` | Apply export mapping to entity, returns string |
175177
| Error handling | `... ON ERROR CONTINUE\|ROLLBACK\|{ handler };` | Not supported on EXECUTE DATABASE QUERY |
176178

177179
## Microflows - NOT Supported (Will Cause Parse Errors)
@@ -345,6 +347,67 @@ CREATE OR REPLACE NAVIGATION Responsive
345347
| Create with name map | `CREATE JSON STRUCTURE Module.Name SNIPPET '...' CUSTOM NAME MAP ('jsonKey' AS 'CustomName', ...);` | Override auto-generated ExposedNames |
346348
| Drop structure | `DROP JSON STRUCTURE Module.Name;` | |
347349

350+
## Import Mappings
351+
352+
| Statement | Syntax | Notes |
353+
|-----------|--------|-------|
354+
| Show mappings | `SHOW IMPORT MAPPINGS [IN Module];` | List all or filter by module |
355+
| Describe mapping | `DESCRIBE IMPORT MAPPING Module.Name;` | Re-executable CREATE statement |
356+
| Create mapping | See below | Assignment syntax: `Attr = jsonField` |
357+
| Drop mapping | `DROP IMPORT MAPPING Module.Name;` | |
358+
359+
```sql
360+
CREATE IMPORT MAPPING Module.IMM_Pet
361+
WITH JSON STRUCTURE Module.JSON_Pet
362+
{
363+
CREATE Module.PetResponse {
364+
PetId = id KEY,
365+
Name = name,
366+
Status = status
367+
}
368+
};
369+
```
370+
371+
**Object handling:** `CREATE` (default), `FIND` (requires KEY), `FIND OR CREATE`
372+
373+
**Nested objects:** Use association path `Assoc/Entity = jsonKey`:
374+
```sql
375+
CREATE Module.OrderResponse_CustomerInfo/Module.CustomerInfo = customer {
376+
Email = email,
377+
Name = name
378+
}
379+
```
380+
381+
## Export Mappings
382+
383+
| Statement | Syntax | Notes |
384+
|-----------|--------|-------|
385+
| Show mappings | `SHOW EXPORT MAPPINGS [IN Module];` | List all or filter by module |
386+
| Describe mapping | `DESCRIBE EXPORT MAPPING Module.Name;` | Re-executable CREATE statement |
387+
| Create mapping | See below | Assignment syntax: `jsonField = Attr` |
388+
| Drop mapping | `DROP EXPORT MAPPING Module.Name;` | |
389+
390+
```sql
391+
CREATE EXPORT MAPPING Module.EMM_Pet
392+
WITH JSON STRUCTURE Module.JSON_Pet
393+
NULL VALUES LeaveOutElement
394+
{
395+
Module.PetResponse {
396+
id = PetId,
397+
name = Name,
398+
status = Status
399+
}
400+
};
401+
```
402+
403+
**Nested objects:** Use association path `Assoc/Entity AS jsonKey`:
404+
```sql
405+
Module.OrderResponse_CustomerInfo/Module.CustomerInfo AS customer {
406+
email = Email,
407+
name = Name
408+
}
409+
```
410+
348411
## Java Actions
349412

350413
| Statement | Syntax | Notes |

mdl-examples/doctype-tests/06-rest-client-examples.mdl

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,67 @@ END;
13821382
/
13831383

13841384
-- ############################################################################
1385-
-- PART 16: VERIFICATION COMMANDS
1385+
-- PART 16: IMPORT/EXPORT MAPPING IN MICROFLOWS
1386+
-- ############################################################################
1387+
1388+
-- MARK: Import/Export Mapping Actions
1389+
1390+
-- ============================================================================
1391+
-- Level 16.1: Import from Mapping (with result variable)
1392+
-- ============================================================================
1393+
--
1394+
-- Applies an import mapping to a JSON string to produce entity objects.
1395+
-- The result is stored in a variable for further processing.
1396+
1397+
CREATE MICROFLOW RestTest.ACT_ImportFromMapping ()
1398+
RETURNS Boolean AS $Success
1399+
BEGIN
1400+
DECLARE $Success Boolean = false;
1401+
DECLARE $JsonContent String = '{{\"id\": 1, \"name\": \"Fido\", \"status\": \"available\"}';
1402+
1403+
$PetResponse = IMPORT FROM MAPPING RestTest.IMM_Pet($JsonContent);
1404+
1405+
IF $PetResponse != empty THEN
1406+
SET $Success = true;
1407+
LOG INFO NODE 'RestTest' 'Import succeeded: ' + $PetResponse/Name;
1408+
END IF;
1409+
1410+
RETURN $Success;
1411+
END;
1412+
/
1413+
1414+
-- ============================================================================
1415+
-- Level 16.2: Export to Mapping (entity to JSON string)
1416+
-- ============================================================================
1417+
--
1418+
-- Applies an export mapping to an entity object to produce a JSON string.
1419+
1420+
CREATE MICROFLOW RestTest.ACT_ExportToMapping ($PetResponse: RestTest.PetResponse)
1421+
RETURNS String AS $JsonOutput
1422+
BEGIN
1423+
$JsonOutput = EXPORT TO MAPPING RestTest.EMM_Pet($PetResponse);
1424+
LOG INFO NODE 'RestTest' 'Exported JSON: ' + $JsonOutput;
1425+
RETURN $JsonOutput;
1426+
END;
1427+
/
1428+
1429+
-- ============================================================================
1430+
-- Level 16.3: Import → Process → Export pipeline
1431+
-- ============================================================================
1432+
--
1433+
-- Full pipeline: receive JSON, import to entities, process, export back to JSON.
1434+
1435+
CREATE MICROFLOW RestTest.ACT_ImportProcessExport ()
1436+
BEGIN
1437+
DECLARE $JsonContent String = '{{\"id\": 1, \"name\": \"Fido\", \"status\": \"available\"}';
1438+
$PetResponse = IMPORT FROM MAPPING RestTest.IMM_Pet($JsonContent);
1439+
$PetResponseJson = EXPORT TO MAPPING RestTest.EMM_Pet($PetResponse);
1440+
LOG INFO NODE 'RestTest' 'Round-tripped: ' + $PetResponseJson;
1441+
END;
1442+
/
1443+
1444+
-- ############################################################################
1445+
-- PART 17: VERIFICATION COMMANDS
13861446
-- ############################################################################
13871447

13881448
-- MARK: Verification

mdl/ast/ast_microflow.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,3 +623,25 @@ type SendRestRequestStmt struct {
623623
}
624624

625625
func (s *SendRestRequestStmt) isMicroflowStatement() {}
626+
627+
// ImportFromMappingStmt represents: [$Var =] IMPORT FROM MAPPING Module.IMM($SourceVar)
628+
type ImportFromMappingStmt struct {
629+
OutputVariable string // Optional result variable (without $)
630+
Mapping QualifiedName // Import mapping qualified name
631+
SourceVariable string // Input string variable (without $)
632+
ErrorHandling *ErrorHandlingClause // Optional ON ERROR clause
633+
Annotations *ActivityAnnotations // Optional @position, @caption, @color, @annotation
634+
}
635+
636+
func (s *ImportFromMappingStmt) isMicroflowStatement() {}
637+
638+
// ExportToMappingStmt represents: $Var = EXPORT TO MAPPING Module.EMM($SourceVar)
639+
type ExportToMappingStmt struct {
640+
OutputVariable string // Result string variable (without $)
641+
Mapping QualifiedName // Export mapping qualified name
642+
SourceVariable string // Input entity variable (without $)
643+
ErrorHandling *ErrorHandlingClause // Optional ON ERROR clause
644+
Annotations *ActivityAnnotations // Optional @position, @caption, @color, @annotation
645+
}
646+
647+
func (s *ExportToMappingStmt) isMicroflowStatement() {}

0 commit comments

Comments
 (0)