Skip to content

Commit 1b86f6c

Browse files
akoclaude
andcommitted
feat: redesign consumed REST client syntax and add full mapping support
Redesigns CREATE REST CLIENT to use property-based {} syntax aligned with CREATE PUBLISHED REST SERVICE: CREATE REST CLIENT Module.Api ( BaseUrl: 'https://...', Authentication: NONE ) { OPERATION GetItems { Method: GET, Path: '/items/{id}', Parameters: ($id: String), Query: ($q: String), Headers: ('Accept' = 'application/json'), Response: MAPPING Module.ItemResponse { "Id" = "id", } } }; New capabilities: - Body: TEMPLATE '...' (Rest$StringBody with value template) - Body: MAPPING Entity { jsonField = Attr } (Rest$ImplicitMappingBody) - Response: MAPPING Entity { Attr = jsonField } (Rest$ImplicitMappingResponseHandling) - Nested object mappings: CREATE Assoc/Entity = jsonField { ... } - JsonPath comments in DESCRIBE for tracing JSON flattening - Query param types now parsed correctly (was hardcoded to String) - DESCRIBE always double-quotes mapping identifiers for roundtrip safety - Version feature keys and checkFeature() for published REST commands - Documentation: quick reference, help topics, docs-site examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f0d16f0 commit 1b86f6c

File tree

20 files changed

+12011
-10815
lines changed

20 files changed

+12011
-10815
lines changed

cmd/mxcli/help_topics/rest.txt

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

18+
CREATE REST CLIENT
19+
------------------
20+
21+
CREATE REST CLIENT Module.Api (
22+
BaseUrl: 'https://api.example.com',
23+
Authentication: NONE
24+
)
25+
{
26+
OPERATION GetOrder {
27+
Method: GET,
28+
Path: '/orders/{id}',
29+
Parameters: ($id: String),
30+
Headers: ('Accept' = 'application/json'),
31+
Timeout: 30,
32+
Response: JSON AS $Result
33+
}
34+
35+
OPERATION CreateOrder {
36+
Method: POST,
37+
Path: '/orders',
38+
Headers: ('Content-Type' = 'application/json'),
39+
Body: MAPPING Module.OrderRequest {
40+
customerId = CustomerId,
41+
amount = Amount,
42+
},
43+
Response: MAPPING Module.OrderResponse {
44+
Id = id,
45+
Status = status,
46+
}
47+
}
48+
};
49+
50+
CREATE OR MODIFY REST CLIENT Module.Api ( ... ) { ... }; -- Update existing
51+
DROP REST CLIENT Module.Api;
52+
53+
Authentication: NONE | BASIC (Username: '...', Password: '...')
54+
Body: JSON FROM $var | TEMPLATE '...' | MAPPING Entity { jsonField = Attr, ... }
55+
Response: JSON AS $var | STRING AS $var | FILE AS $var | STATUS AS $var | NONE
56+
| MAPPING Entity { Attr = jsonField, ... }
57+
1858
CREATE / DROP PUBLISHED REST SERVICE
1959
-------------------------------------
2060

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

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,67 @@ CREATE IMPORT MAPPING Integration.IMM_Order
180180
};
181181
```
182182

183+
## Consuming a REST API
184+
185+
Define a reusable REST client with typed operations using `CREATE REST CLIENT`. Each operation declares its method, path, optional parameters, headers, body, and response mapping.
186+
187+
```sql
188+
-- Define a client for the orders API
189+
CREATE REST CLIENT Integration.OrdersApi (
190+
BaseUrl: 'https://api.example.com/v1',
191+
Authentication: NONE
192+
)
193+
{
194+
OPERATION GetOrder {
195+
Method: GET,
196+
Path: '/orders/{id}',
197+
Parameters: ($id: String),
198+
Headers: ('Accept' = 'application/json'),
199+
Timeout: 30,
200+
Response: JSON AS $Result
201+
}
202+
203+
OPERATION CreateOrder {
204+
Method: POST,
205+
Path: '/orders',
206+
Headers: ('Content-Type' = 'application/json'),
207+
Body: MAPPING Integration.OrderRequest {
208+
customerId = CustomerId,
209+
totalAmount = TotalAmount,
210+
notes = Notes,
211+
},
212+
Response: MAPPING Integration.OrderResponse {
213+
Id = id,
214+
Status = status,
215+
CreatedAt = createdAt,
216+
}
217+
}
218+
};
219+
```
220+
221+
Use `CREATE OR MODIFY REST CLIENT` to update an existing client without dropping it first:
222+
223+
```sql
224+
CREATE OR MODIFY REST CLIENT Integration.OrdersApi (
225+
BaseUrl: 'https://api.example.com/v2',
226+
Authentication: BASIC (Username: 'apiuser', Password: 'secret')
227+
)
228+
{
229+
OPERATION GetOrder {
230+
Method: GET,
231+
Path: '/orders/{id}',
232+
Parameters: ($id: String),
233+
Headers: ('Accept' = 'application/json'),
234+
Timeout: 60,
235+
Response: JSON AS $Result
236+
}
237+
};
238+
```
239+
240+
**Body types:** `JSON FROM $var`, `TEMPLATE '...'`, `MAPPING Entity { jsonField = Attr, ... }`
241+
**Response types:** `JSON AS $var`, `STRING AS $var`, `FILE AS $var`, `STATUS AS $var`, `NONE`, `MAPPING Entity { Attr = jsonField, ... }`
242+
**Authentication:** `NONE`, `BASIC (Username: '...', Password: '...')`
243+
183244
## Publishing a REST API
184245

185246
Create a published REST service with CRUD operations backed by microflows.

docs/01-project/MDL_QUICK_REFERENCE.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,52 @@ CREATE OR REPLACE NAVIGATION Responsive
439439

440440
**Export levels:** `'Hidden'` (default, internal to module), `'Public'` (accessible from other modules).
441441

442+
## Consumed REST Services
443+
444+
| Statement | Syntax | Notes |
445+
|-----------|--------|-------|
446+
| Show clients | `SHOW REST CLIENTS [IN Module];` | List all or filter by module |
447+
| Describe client | `DESCRIBE REST CLIENT Module.Name;` | Re-executable CREATE |
448+
| Create client | See syntax below | Property-based `{}` syntax |
449+
| Create or modify | `CREATE OR MODIFY REST CLIENT ...` | Replaces existing |
450+
| Drop client | `DROP REST CLIENT Module.Name;` | |
451+
452+
```sql
453+
CREATE REST CLIENT Module.Api (
454+
BaseUrl: 'https://api.example.com',
455+
Authentication: NONE
456+
)
457+
{
458+
OPERATION GetItems {
459+
Method: GET,
460+
Path: '/items/{id}',
461+
Parameters: ($id: String),
462+
Query: ($filter: String),
463+
Headers: ('Accept' = 'application/json'),
464+
Timeout: 30,
465+
Response: JSON AS $Result
466+
}
467+
468+
OPERATION CreateItem {
469+
Method: POST,
470+
Path: '/items',
471+
Headers: ('Content-Type' = 'application/json'),
472+
Body: MAPPING Module.ItemRequest {
473+
name = Name,
474+
price = Price,
475+
},
476+
Response: MAPPING Module.ItemResponse {
477+
Id = id,
478+
Status = status,
479+
}
480+
}
481+
};
482+
```
483+
484+
**Body types:** `JSON FROM $var`, `TEMPLATE '...'`, `MAPPING Entity { jsonField = Attr, ... }`
485+
**Response types:** `JSON AS $var`, `STRING AS $var`, `FILE AS $var`, `STATUS AS $var`, `NONE`, `MAPPING Entity { Attr = jsonField, ... }`
486+
**Authentication:** `NONE`, `BASIC (Username: '...', Password: '...')`
487+
442488
## Published REST Services
443489

444490
| Statement | Syntax | Notes |

0 commit comments

Comments
 (0)