Codegen entity meta-model — C++ protocol

Table of Contents

This page is a segment of the Codegen org-entity meta-model hub, covering the ores.cpp.protocol facet.

What this facet is, and what it isn't

Protocol is data shape only — the request/response message structs an entity's NATS API exchanges. It has no behaviour: no networking code, no dispatch logic. That belongs to C++ NATS, which consumes these struct definitions on both the sending and receiving side. C++ Qt's Naming/wiring knobs (:get_request_class:, :save_message_type:, etc.) also just reference class/type names that this facet defines.

Physical model mapping

Facet Description
ores.cpp.protocol Protocol (de)serialisation.

What gets generated, unconditionally

For every entity: a get/list request+response pair, a save request+response pair, a delete request+response pair, and a history request+response pair — no knobs control whether these exist.

Generates, in book_protocol.hpp:

namespace ores::refdata::messaging {

struct get_books_request {
    using response_type = struct get_books_response;
    static constexpr std::string_view nats_subject = "refdata.v1.books.list";
    std::uint32_t offset = 0;
    std::uint32_t limit = 100;
};

struct get_books_response {
    std::vector<ores::refdata::domain::book> books;
    int total_available_count = 0;
    bool success = false;
    std::string message;
};

struct save_book_request {
    using response_type = struct save_book_response;
    static constexpr std::string_view nats_subject = "refdata.v1.books.save";
    ores::refdata::domain::book data;

    static save_book_request from(ores::refdata::domain::book v) {
        return {.data = std::move(v)};
    }
};

// ... save_book_response, delete_book_request/response, history request/response ...

}

Every request struct's nats_subject follows <component>.v1.<entity_plural>.<verb> — this is what C++ NATS's sub-registrar wires each handler method to.

Paste blocks

The ores.cpp.protocol facet defines the following paste block kinds, one per sub-heading below — see Paste blocks for the general mechanism they assume.

Custom message includes

Additional #include directives injected after the standard generated includes, expecting a body block. Use for domain headers needed by the custom message types below — e.g. a child entity's domain header for a composite as-of response.

Custom message types

Additional request/response struct definitions injected after the standard generated structs (and the has_parent_id hierarchy structs, if SQL's hierarchy knob is set), still inside the messaging namespace, expecting a body block. Use for entity-specific NATS message types beyond the standard CRUD surface — a bulk cache-warming read, a composite as-of read spanning a parent and its child entities. Pairs with C++ NATS's "custom public methods" and "custom subscription" paste points, to wire the full request/handler/subscription trio.

To use this paste block on an entity, declare it under ** Paste blocks > *** Custom message types. See the following example, from party's composite-as-of read:

** Paste blocks
*** Custom message types

#+begin_src cpp :name composite_as_of_messages :implements 2C4E8F1A-6B9D-4A3E-8F2C-7D1E5A9B3C6F
struct get_party_composite_as_of_request {
    using response_type = struct get_party_composite_as_of_response;
    static constexpr std::string_view nats_subject = "refdata.v1.parties.composite_as_of";
    std::string id;
    int version = 0;
};

struct get_party_composite_as_of_response {
    bool success = false;
    std::string message;
    ores::refdata::domain::party party;
    std::vector<ores::refdata::domain::party_identifier> identifiers;
    std::vector<ores::refdata::domain::party_contact_information> contacts;
};
#+end_src

See also

  • Codegen org-entity meta-model — the hub.
  • C++ NATS — consumes these message types on both the request and the changed-event side.
  • C++ Qt — references these class/subject names by name in its Naming/wiring knobs.

Emacs 29.3 (Org mode 9.6.15)