Skip to content

Entities & DTOs

This page explains how to model data in the canonical model:

  • simple and complex data types
  • DTO-style types used for API payloads
  • the idea of entities and how platforms use them

The focus is on the canonical model (.cmn). Platform-specific interpretation (for example JPA entities) is handled by cartridges and platform profiles, which are covered on the Profiles & platforms page.


1. Data types in the canonical model

Data types represent the information in your domain. In CMN you work with:

  • base types – primitive types provided by shared models
  • simple types – aliases or constrained specialisations of base types
  • complex types – structured types with named properties
  • enums – finite sets of values (conceptual overview here, details in DSL reference)

A typical model file starts with a package and imports:

text
package com.example.joinedworkz.quickstart

import org.joinedworkz.facilities.common.base.api

The imported base model contributes common types such as String and predefined method types like create and read.

1.1 Base and simple types

Base models (for example common-base) define reusable primitive types. A simplified example from such a model is:

text
type<string> String(maxLength) maxLength=undefined

This defines a simple type String based on the primitive string, with an optional maxLength parameter. Other simple types in your own models can follow the same pattern, for example a type representing an ID or a constrained numeric value.

Simple types are useful when you want:

  • a distinct type in your domain model (for clarity and type safety),
  • optional constraints or metadata (for validation and generation),
  • but no structured properties.

1.2 Complex types

Complex types group multiple named properties into a single structure.

The quickstart example contains a very simple complex type:

text
type Greeting {
    message: String
}

Here:

  • Greeting is a complex type.
  • It has one property message of type String (from the imported base model).

Complex types typically model:

  • request and response payloads,
  • domain entities (when combined with stereotypes, see below),
  • configuration objects or other structured data.

You can add more properties and reference other types from the same or imported packages, forming your domain model.

1.3 Enums (conceptual)

Enums represent a finite set of values (for example NEW, CONFIRMED, SHIPPED). They are useful for:

  • states,
  • categories,
  • flags where only known values are allowed.

The exact DSL syntax for enums is described in the CMN reference. From the modeling perspective you should think of enums as closed sets of values that generators can treat in a type-safe way.


2. DTO-style types

Most complex types in the canonical model are DTO-like (Data Transfer Objects):

  • they describe the shape of data exchanged between parts of the system, or between your system and external clients;
  • they are technology-neutral – there is no mention of JSON, XML, JPA, etc.;
  • they can be reused across services, resources and components.

Examples of how DTO-style types are typically used:

  • as request and response types of service methods;
  • as payload types of resource methods/endpoints;
  • as types of events or messages in messaging scenarios.

From the canonical model’s point of view there is no strict technical difference between a “DTO” and any other complex type. The distinction usually comes from:

  • naming and intent (e.g. GreetingResponse),
  • stereotypes and platform profiles, which tell generators what to do with a type.

Platforms can choose to map DTO-style types to:

  • Java classes used in controller signatures,
  • transfer objects used by clients,
  • schemas in OpenAPI documents, etc.

3. Entities

In many systems you also have entities – types that represent business objects with an identity, which may be persisted or tracked over time.

In the canonical model, entities are usually expressed as complex types that are marked with a suitable stereotype (for example entity). The exact syntax and list of available stereotypes is defined in the platform profiles and base models used by your project.

Conceptually, an entity has:

  • one or more properties that form its identity (such as an ID),
  • additional attributes that describe its state,
  • potentially relationships to other entities.

Examples of how platforms may treat entity types:

  • persistence platforms may map entities to database tables (e.g. via JPA),
  • service platforms may generate repository/service interfaces,
  • API platforms may expose entity representations via resources.

It is important to note:

  • An entity in the canonical model does not have to be a persisted entity in every platform. Some platforms may treat it as a logical or business entity only.
  • Complex types without the entity stereotype are typically treated as DTOs or value objects, depending on the platform.

The detailed syntax for defining stereotypes and their effect on generation is covered on the Profiles & platforms (.profil) page.


4. How platforms use types, DTOs and entities

Platforms and cartridges interpret your types according to their own rules. For example, a typical REST + persistence stack might:

  • use DTO-style complex types for request/response objects in controllers,
  • use entity-marked complex types for persistence mappings,
  • reuse base and simple types for validation constraints and schema generation (e.g. OpenAPI schemas, Bean Validation annotations).

You keep your canonical model free from framework details and let the platform decide:

  • which types are persisted,
  • which types are only used for transport,
  • which conventions (naming, layering) apply.

This separation lets you:

  • switch or evolve platforms over time,
  • reuse the same canonical model with different technology stacks,
  • keep your domain concepts stable while changing implementation details.

5. Next steps

From here you can:

  • dive into APIs to see how types are used in services, resources and endpoints;
  • read about Components to understand how types and APIs are grouped into deployable units;
  • explore Profiles & platforms to see how stereotypes and platform-specific rules interpret your types;
  • consult the CMN reference for exact syntax of type and enum definitions.