Fix: persist and read back consumed REST operation mappings (#843) - #99
Merged
Conversation
…bs#843) A `create rest client` operation reported success, but `describe rest client` omitted Query/Parameters/Headers and always printed `Response: none`. Dumping the stored BSON showed the query parameters and headers written correctly while ResponseHandling was Rest$NoResponseHandling — the response mapping was gone. `mx check` reported 0 errors, so nothing anywhere complained. Three independent defects behind the one symptom. Write path. model.RestClientOperation documents BodyType/ResponseType as upper-case tokens, and every consumer compares against that spelling: both serializers and the REST-call microflow builder. The MDL executor stored the visitor's lower-case source text, so `op.ResponseType == "MAPPING"` never matched and the mapping fell through to the else-branch — which legitimately writes "no response handling". Nothing errored because that is a real outcome for an operation without a mapping; the mismatch was laundered into a plausible model. Normalized with strings.ToUpper at the one place the AST becomes the semantic model, and made the two serializer comparisons EqualFold so the same landmine is not left armed for the next producer (the OpenAPI import path already emits the upper-case form). Read path. restOperationFromGen populated only Name/HttpMethod/Path/ Timeout and type-asserted Rest$RestParameter for both parameter lists, while the writer emits Rest$OperationParameter and Rest$QueryParameter — two different gen types, so both assertions failed to ok=false and skipped every item. Headers and ResponseHandling were not read at all. Now reads parameters (with DataType), query parameters, headers, the response handler and the body, including the Import/ExportMappings element trees. This also repairs shouldSetBodyVariable, which could never see EXPORT_MAPPING because BodyType was never populated. Unsupported reference syntax. `Response: mapping Mod.IMM_X` — what the reporter wrote — names an import mapping *document*. The clause expects a target entity plus a `{ ... }` body, and Mendix has nowhere to store a document reference: Rest$RestOperationResponseHandling has exactly two implementations, inline-mapping and none. It parsed, contributed no entries, and was written as "none". Now refused at exec time and at `mxcli check` time (MDL-REST01, no project required), with the inline form spelled out in the message. Rest$QueryParameter stores no DataType, so the MDL type is decorative and dropped at write time. describe now re-emits query parameters as String rather than an empty type, which did not re-parse. Verified on Mendix 11.13.0: reporter's script now fails loudly instead of silently; the corrected script stores Rest$ImplicitMappingResponseHandling with a full ImportMappings$ObjectMappingElement tree, mx check reports 0 errors, and describe -> exec -> describe is byte-identical. Each of the three fixes was reverted independently to confirm it is the cause of its test's failure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LUToAkUx54bNkNjsBpufRH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes mendixlabs#843.
Symptom
create rest clientreports success.describe rest clientthen omitsQuery:,Parameters:andHeaders:entirely, and always printsResponse: none.mx checkreports 0 errors, so nothing anywhere complains.Dumping the stored BSON for the reporter's script shows the split:
Three defects behind one symptom
1. Write path — a case-sensitive comparison whose false branch is silent
model.RestClientOperationdocumentsBodyType/ResponseTypeas upper-case tokens, and every consumer compares against that spelling — both serializers and the REST-call microflow builder. The MDL executor stored the visitor's lower-case source text:The mapping was dropped on every response mapping authored in MDL, not just the reporter's syntax — a fully correct
Response: mapping Mod.Entity { Attr = field }was lost too. Nothing errored because the else-branch is a legitimate outcome for an operation with no mapping, so a producer/consumer mismatch got laundered into a plausible-looking model.Fixed by normalizing with
strings.ToUpperat the one place the AST becomes the semantic model, and making the two serializer comparisonsEqualFoldso the landmine isn't left armed for the next producer. (The OpenAPI import path already emits the documented upper-case form, which is why it was unaffected.)2. Read path — one type assertion for two different gen types
restOperationFromGenpopulated only Name/HttpMethod/Path/Timeout, and type-asserted*genRest.RestParameterfor both parameter lists. The writer emitsRest$OperationParameterandRest$QueryParameter— two different types — so both assertions fell took=falseand skipped every item. Headers andResponseHandlingweren't read at all.Now reads parameters (with DataType), query parameters, headers, the response handler and the body, including the
ImportMappings/ExportMappingselement trees. This also repairsshouldSetBodyVariable, which could never observeEXPORT_MAPPINGbecauseBodyTypewas never populated.3. The reporter's actual syntax is not expressible in Mendix
Response: mapping ZZB."IMM_R10"names an import mapping document. The clause expects a target entity plus a{ ... }body — Mendix stores the mapping inline on the operation and has nowhere to put a document reference.Rest$RestOperationResponseHandlinghas exactly two implementations:So it parsed, named a document where an entity belongs, contributed no field mappings, and was written as "no response handling" — in silence. Now refused at exec time and at
mxcli checktime (MDL-REST01, no project needed):One deliberate non-fix
Rest$QueryParameterstores noDataType— Mendix does not model a type for query parameters, so the one written in MDL is dropped at write time and there is nothing to read back. The grammar still requires$name: Type, sodescribeemitted$page:, which does not re-parse. It now emitsString. Reconstructing the authored type would be inventing a value the model does not hold — the mistake fixed in mendixlabs#840.Validation
Mendix 11.13.0, fresh projects via
mxcli new:ResponseHandlingRest$NoResponseHandlingRest$ImplicitMappingResponseHandling+ fullImportMappings$ObjectMappingElementtreedescribe rest clientResponse: none, no Query/Parameters/Headersmx checkParameters = 0, want 1/lowercase "mapping" lost the response mapping/ResponseType = "json", want "JSON").go test ./...,make check-mdlgreen.Changes
mdl/executor/cmd_rest_clients.gocheckInlineMappingBody;restParamTypeOrDefaultmdl/backend/modelsdk/integration_read.gomdl/backend/modelsdk/consumed_rest_write.goEqualFoldon the two silent-drop comparisonsmodelsdk/mpr/serialize_web_services.gomdl/executor/validate_rest_mapping.goMDL-REST01check-time rulecmd/mxcli/cmd_check.gocmd/mxcli/syntax/features_integration.goQuery:/Timeout:in help; entity-not-document note.claude/skills/mendix/rest-client.md.claude/skills/fix-issue.mdmdl-examples/bug-tests/843-*.mdl.fail.mdlnegative test🤖 Generated with Claude Code
https://claude.ai/code/session_01LUToAkUx54bNkNjsBpufRH
Generated by Claude Code