fix(mqtt,nats): align generated wire protocols with the agreed ApiGear scheme - #11
Merged
Conversation
The per-interface `*Data` structs (used to deserialize the full property snapshot for NATS init/state and OLink) had snake_case field names but no serde rename, so they could not parse the camelCase IDL keys the wire actually carries (e.g. `propInt`). State snapshots silently fell back to default values. Add `#[serde(rename = "<IDL name>")]` per field so the keys match the wire and the other ApiGear templates.
The NATS adapters diverged from the scheme used by the C++/Qt/Python templates. Bring them in line so a Rust client/service interoperates over the same nats-server: - subjects: drop the `apigear.` prefix; operations use `rpc.<op>` (was `op.<op>`); split the single `prop.<p>` into `set.<p>` (client->service request) and `prop.<p>` (service->client notification), which also removes a self-echo on the service. - availability/state: announce `service.available` and answer the `init` handshake on `init.resp.<clientId>` instead of the bespoke `state` subject. The client id is a number, matching the other templates.
Bring the MQTT adapters in line with the C++/Qt/Python templates so a Rust client/service interoperates over the same broker: - migrate the adapters to rumqttc's MQTT 5 client; operations use `rpc/<op>` with the MQTT 5 ResponseTopic + CorrelationData properties and the reply is correlated and awaited (previously the client published an `op/<op>/req` request and silently dropped the response). - drop the `apigear/` prefix; split the single `prop/<p>` into `set/<p>` (change request) and retained `prop/<p>` (notification); drop the bespoke `state` topic — retained `prop/` messages carry the current state.
Document the agreed topic/subject scheme (rpc/set/prop/sig, MQTT 5 correlation, NATS service.available + init handshake) and the updated adapter API (rumqttc v5, client id constructor argument).
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.
Summary
The generated Rust MQTT and NATS adapters had diverged from the agreed ApiGear wire scheme that the C++17/Qt/Python templates implement, so a Rust client/service could not interoperate with them over the same broker. This aligns both transports with the spec (verified against the C++17 code, not the PDFs — the NATS PDF's swapped property verbs are a known documentation error).
MQTT
ResponseTopic+CorrelationDataproperties.rpc/<op>; the client now correlates and awaits the reply (previously it publishedop/<op>/reqand silently dropped the response).apigear/prefix; split the singleprop/<p>intoset/<p>(change request) and retainedprop/<p>(notification); drop the bespokestatetopic (retainedprop/carries the state).NATS
apigear.prefix; operations userpc.<op>(wasop.<op>).prop.<p>intoset.<p>(request) andprop.<p>(notification) — this also removes a service-side self-echo.service.availableand answer theinithandshake oninit.resp.<clientId>(numeric id) instead of the bespokestatesubject.Core
*Datastate structs now serialize with the IDL property names (#[serde(rename = "...")]), so the camelCase wire keys actually deserialize. Previously the snapshot silently fell back to defaults (affected NATS init/state and OLink).Resulting wire scheme (
tb.simple/SimpleInterface)/).)…/rpc/<op>(+ MQTT5 ResponseTopic/CorrelationData)….rpc.<op>(request/reply)…/set/<p>….set.<p>…/prop/<p>(retained)….prop.<p>…/sig/<p>….sig.<p>….service.available+….init→….init.resp.<id>Verification
cargo fmt --check,clippy -D clippy::correctness -D clippy::perf,cargo doc -D warnings: cleango run main.go diff): cleanpropInt/propString, and the Rust client's RPC round-trips against the C++ server.Commits
fix(core): serialize interface state with IDL property namesfix(nats): align generated wire protocol with the agreed ApiGear schemefix(mqtt): align generated wire protocol with the agreed ApiGear schemedocs: update MQTT/NATS feature docs for the corrected wire scheme