← All guides Code generation

Generate code from your model.

EOModeller doesn't bake a code generator into the app. Instead it exports a clean, fully-resolved model JSON, and a small script you run locally turns it into whatever your toolchain needs — CQL, DDL, code, IaC. You see and diff exactly what's produced, and the app never runs anyone else's script.

The loop

  1. Export the model as JSON from EOModeller.
  2. Run a generation script against it, locally.
  3. Review the output and apply it (commit it, run it, ship it).
The app never executes generation scripts. You export data; you run the script yourself after reading it. A malicious or buggy script can't reach your model or servers — it only ever sees the JSON file you handed it. That's the whole security model: generation stays in your control.

Step 1 — Export the model JSON

Open the model, go to the model export panel, and click JSON (next to XMI). You get <ModelName>.model.json — a flat, semantic view of the model built for scripting.

Prefer the command line or automation? The same export is a stable API endpoint (auth with a personal access token — see the XMI guide for minting one):

GET /api/workspaces/<workspaceId>/models/<modelId>/export/model.json
       Authorization: Bearer eo_pat_…

Add ?visual=true to also embed per-element geometry and style — the same format then doubles as an embedded model for images. Code generators ignore that block.

What's in the JSON

The export is deliberately easy to parse — no XML, no cross-reference chasing, no stereotype lookups. Everything is resolved:

  • Elements and relationships as flat, id-keyed arrays; declared attribute/operation order is preserved.
  • Stereotypes carry their resolved name and owning profile — so a column marked «K» shows up as { "stereotype": "K", "profileId": "cassandra" }, no registry needed.
  • Tagged values flattened to a plain { name: value } map.
  • profilesApplied at the top, so a script can check whether the profile it targets is present before doing anything.

A class with the Cassandra «table» stereotype and a few marked columns exports like this:

{
  "formatVersion": "1.0",
  "profilesApplied": [{ "profileId": "cassandra", "name": "Cassandra" }],
  "elements": [{
    "name": "UsersByCity",
    "stereotypes": [{ "stereotype": "table", "profileId": "cassandra" }],
    "attributes": [
      { "name": "city",     "type": "text", "stereotypes": [{ "stereotype": "K"  }] },
      { "name": "username", "type": "text", "stereotypes": [{ "stereotype": "C↑" }] },
      { "name": "email",    "type": "text", "stereotypes": [] }
    ]
  }]
}

Step 2 — Get (or write) a script

A script reads the JSON and writes your target artefact. The reference implementation is a Cassandra CQL generator for the Chebotko notation — Python, standard library only, no dependencies. It maps the profile straight onto DDL:

In the modelGenerated CQL
«table» on a classCREATE TABLE
«udt» on a classCREATE TYPE
«K» columnpartition key (composite = several, in order)
«C↑» / «C↓» columnclustering column, ASC / DESC
«S» columnSTATIC column
«IDX» columnCREATE INDEX
column typethe CQL type verbatim (text, uuid, set<text>, …)

Step 3 — Run it locally

python3 generate_cql.py UsersByCity.model.json --keyspace shop > schema.cql

The JSON above produces:

CREATE TABLE shop.UsersByCity (
  city text,
  username text,
  email text,
  PRIMARY KEY ((city), username)
)
  WITH CLUSTERING ORDER BY (username ASC);

Partition keys come first and clustering order is preserved because the export keeps your column ordering. Warnings (a table with no partition key, an unsupported format version) go to stderr; the CQL goes to stdout.

Step 4 — Review and apply

Read the generated file — that's the point of doing this locally — then apply it however your target expects:

cqlsh -f schema.cql

Writing your own

The reference script is a template. To target a different database, language, or framework, read the same JSON and emit your own artefact — key off the resolved stereotype names and taggedValues rather than the raw UML type. Ship a small manifest alongside it declaring which profile it consumes and which formatVersion it supports, so it's discoverable and matched to the right models.

The export is a versioned contract. formatVersion is MAJOR.MINOR: minor bumps only add optional fields (backward-compatible); a major bump signals a breaking change, so a script should check the major it supports and refuse anything newer.

What's coming

Today the loop is export → run → apply. Next: an Export to GitHub action that pushes the model JSON straight to a repo, and a shared, community-reviewed library of generation scripts so you can pick one rather than write it. The security model stays the same — scripts run in your CI or on your machine, never inside EOModeller.

ArchiMate® and TOGAF® are registered trademarks of The Open Group. EOModeller is an independent tool and is not affiliated with or endorsed by The Open Group.