Modeling overview
JoinedWorkz uses model-driven development based on a canonical model and platform-specific metamodels. Understanding how these pieces fit together helps you design models that can be reused across different technology stacks.
At a high level there are two modeling levels:
- the canonical model (
.cmnfiles) – what your system should do - the platform metamodel (
.profilefiles) – how this model is realised on a given platform
This page gives you a conceptual overview. Later pages go into syntax details for each topic (data types, services, resources, components, platforms, …).
1. Canonical model (.cmn)
The canonical model describes the functional structure of your system using Canonical Model Notation (CMN). It is intentionally technology-neutral and focuses on what the system does, not on framework or implementation details.
A .cmn model can define the following core elements:
- data types
- reusable fields, relations, constants and constraints
- services
- resources and resource methods
- components
- applications
1.1 Data types
Data types represent the information in your domain. CMN supports:
- simple types – scalar, facility-defined or specialised types (for example
String, numeric types, or custom simple types with limits) - enums – a fixed set of named values
- complex types – structures with named properties and types
Complex types are typically used for:
- API payloads (requests/responses),
- domain entities,
- configuration and other structured data.
The base models (for example common-base) provide reusable simple types such as String and shared utility types. Your own models build on top of these.
1.2 Services
Services group operations that represent business capabilities. A service typically:
- defines a set of methods,
- uses data types from the same package or imported packages,
- is independent of transport or protocol details.
A facility can map services to concrete artifacts such as service interfaces. The CMN declaration itself does not prescribe an implementation technology or promise a particular generated artifact.
1.3 Resources and endpoints
Resources describe externally visible APIs in a more transport-oriented form. They are often used for REST-style APIs.
A resource contains:
- a resource path (for example
/hello), - resource methods / endpoints,
- references to resource method types that declare an HTTP verb and can provide defaults such as status codes or request/response properties.
Resource method types are usually imported from a base model. For example, the create and read method types might be defined as:
methodtype create POST consumes='*' produces=Id success=201
methodtype read GET instance=true produces='*' success=200 errorResponse=ErrorResponseYour model uses create() / read() and inherits the properties of those imported method types. The names and properties in this example are supplied by the Base facility; they are not built-in CMN keywords. A concrete resource method may additionally have a local name, for example read readGreeting(). Here read remains the method-type reference and readGreeting names that one operation.
1.4 Components
Components group resources and services into logical provided boundaries.
A component typically:
- declares that it provides resources (and sometimes services),
- can depend on other components,
- can be interpreted by facility-specific cartridges to produce diagrams, OpenAPI documents, or implementation artifacts.
provide /customers assigns the referenced resource to the component's provided API boundary. It does not by itself state that the component implements the resource or that executable code has been generated.
1.5 Applications
An application represents a logical system boundary and composition of components.
An application:
- lists owned components in
consists of { ... }, - can express dependencies on other components,
- can be used as the scope of application and component diagrams.
Whether this composition becomes an executable application depends on the selected facility and a project-specific application shell. Base uses applications for diagrams; it does not make the CMN declaration itself runnable.
1.6 Packages and layers
Canonical models are organised into packages. A package defines a namespace for types, services, resources and components.
In addition to the package name, a package can belong to a layer. Layers are used to control aspects such as:
- how platforms treat different parts of the model (e.g.
core,api), - which layer-specific directory JoinedWorkz selects within an outlet.
The declared CMN layer normally becomes the effective layer for generated output. A generator can assign a different effective layer to a particular file. An exact layer-specific outlet mapping wins; otherwise the global outlet directory applies.
The layer is a free identifier written before package, for example api package com.example.customer. There is no layer keyword. Selected facilities may attach additional meaning to particular layer names.
2. Platform metamodel (.profile)
While the canonical model describes what the system should do, the platform metamodel describes how that model is realised. Facilities package this metamodel in .profile resources together with the corresponding generator implementations.
A Profile can provide:
- named Platforms such as
Base,JavaorSpringBoot; - Cartridges that group generation behavior;
- Outlets through which Cartridges write files;
- stereotypes and properties consumed by the Platform; and
- additional advanced implementation elements used by built-in Facilities.
Application developers normally do not edit these Profiles. They add the Facility to the model module's Maven dependencies, import its namespaces and select a Platform:
platform BaseThe selected Platform determines which Cartridges interpret that model and which Outlets are available to them. A specialized Platform can inherit active behavior from its base, so SpringBoot, for example, also includes Java and Base generation behavior.
Continue with:
- Profiles and platforms for the normal Consumer workflow;
- Facilities and platforms for supported Platforms, Maven artifacts and outputs; or
- Build a custom Facility for the separate advanced authoring path.
3. Validation and generation workflow
Modeling is closely tied to validation and generation. JoinedWorkz provides validation both in the Studio editor and in cartridges, and generation is optimised for fast feedback.
3.1 Validation in JoinedWorkz Studio
In JoinedWorkz Studio, CMN models are validated at different times and intensities:
- lightweight checks while typing – quick feedback on basic syntax and simple consistency rules,
- normal checks on save – more complete validation of the edited file,
- full checks before generation – thorough validation across model files before generators run.
Validation can also be platform-specific:
- base validation is done on the canonical model,
- cartridges can perform additional checks for a given platform and report errors back into the editor.
All validation messages are shown as close as possible to the affected model element in the editor (for example as markers on the relevant line).
3.2 Generation triggers
In Studio, generation can be triggered in two ways:
- On save – saving a model file can automatically trigger generation for the affected parts of the model.
- Explicit generate command – via the main menu or context menus in the file/package explorer.
Generation progress, logging output and any errors are shown in a dedicated console view. Even for larger models, generation is typically fast (on the order of a few hundred milliseconds up to about one second, with longer times only in exceptional cases).
3.3 Generation via Maven
Outside of Studio, generation is usually performed via the Maven plugin:
- the plugin runs in the chosen build phase (for example
generate-sources), - it loads and validates the models,
- applies the selected platform and cartridges,
- writes the generated artifacts into the configured outlets.
This makes it easy to integrate JoinedWorkz into CI/CD pipelines and build servers without requiring Studio.
4. Where to go next
The following pages go into more detail about individual parts of the modeling stack:
- Entities & DTOs – details on defining simple, enum and complex types.
- APIs and resources – how to model services, resources and methods.
- Components and applications – structuring your system into logical boundaries.
- Pages and Page Conditions – modeling Page data, content and named Page-local conditions independently of a particular output facility.
- Additional public model elements – descriptions, constants, reusable fields, relations and constraints.
- Profiles and platforms – how application models consume Facility-provided Platforms.
- Profile author reference – the supported, release-specific
.profileauthoring subset. - Profile Strategies and calculated properties – deriving Core Model properties for custom Cartridges and generators.
- Profile-controlled property propagation – the advanced contract for transferring Facility-defined CMN properties across model relationships.
- Layers and outlet routing – how to use layers and
joinedworkz.propertiesto control where generated artifacts go.
