Patterns in CALM
Patterns in CALM define reusable architecture templates that can be used to generate new architecture scaffolds and validate that existing architectures conform to a required structure. This “generate + validate” dual use is a key mechanism for reuse and governance across teams.
What is a Pattern?
Patterns describe architecture blueprints. Instead of listing a fixed set of components, a pattern prescribes:
- Which nodes (e.g., services, systems, databases) must exist.
- Which relationships connect those nodes.
- What constraints or choices are required for those nodes and relationships.
- Which fields are structural (governed by the pattern) versus which are descriptive (left for implementation).
Because they’re expressed in JSON Schema, patterns use familiar constraints such as:
- const to enforce fixed values that identify required elements,
prefixItemsandminItems/maxItemsto require specific arrays of elements, andoneOf/anyOfto offer allowable alternatives (e.g., different database options).
This schema-based definition makes patterns self-validating, versionable, and compatible with existing tooling.
Key Properties of Patterns
Patterns are primarily about structural intent—what must exist and how it must connect:
- Structural identifiers (fixed): commonly constrained with
const(e.g., nodeunique-id,node-type, relationshipunique-id, sometimesname). - User-authored fields (open but required): fields like
descriptionare typically left as"type": "string"(and may be required), so generated architectures include placeholders that users should replace. - Required arrays of components:
prefixItems+minItems/maxItemsare commonly used to require a specific set/count of nodes and relationships. - Choices:
anyOf/oneOfcan model “pick one of these components/topologies” patterns.
Example pattern template
Below is a small 3-tier web application pattern template (frontend → API → database) that enforces exactly 3 nodes and exactly 2 relationships, while leaving description user-fillable.
{
"$schema": "https://calm.finos.org/release/1.2/meta/calm.json",
"$id": "https://example.com/patterns/web-app-pattern.json",
"title": "Web Application Pattern",
"description": "A reusable 3-tier web application pattern (frontend, API service, database).",
"type": "object",
"properties": {
"nodes": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"prefixItems": [
{
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
"type": "object",
"properties": {
"unique-id": { "const": "web-frontend" },
"node-type": { "const": "webclient" },
"name": { "const": "Web Frontend" },
"description": { "type": "string" }
},
"required": ["description"]
},
{
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
"type": "object",
"properties": {
"unique-id": { "const": "api-service" },
"node-type": { "const": "service" },
"name": { "const": "API Service" },
"description": { "type": "string" }
},
"required": ["description"]
},
{
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/node",
"type": "object",
"properties": {
"unique-id": { "const": "app-database" },
"node-type": { "const": "database" },
"name": { "const": "Application Database" },
"description": { "type": "string" }
},
"required": ["description"]
}
]
},
"relationships": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"prefixItems": [
{
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/relationship",
"type": "object",
"properties": {
"unique-id": { "const": "frontend-to-api" },
"description": { "type": "string" },
"protocol": { "const": "HTTPS" },
"relationship-type": {
"const": {
"connects": {
"source": { "node": "web-frontend" },
"destination": { "node": "api-service" }
}
}
}
},
"required": ["description"]
},
{
"$ref": "https://calm.finos.org/release/1.2/meta/core.json#/defs/relationship",
"type": "object",
"properties": {
"unique-id": { "const": "api-to-database" },
"description": { "type": "string" },
"protocol": { "const": "JDBC" },
"relationship-type": {
"const": {
"connects": {
"source": { "node": "api-service" },
"destination": { "node": "app-database" }
}
}
}
},
"required": ["description"]
}
]
}
},
"required": ["nodes", "relationships"]
}
This template follows the same techniques shown in the CALM Patterns guidance: use const for structural identity and prefixItems/minItems/maxItems to require exact architecture shape, while keeping human-authored fields open but required.
Using Patterns effectively
Generate an architecture scaffold
calm generate -p patterns/web-app-pattern.json -o architectures/generated-webapp.json
This creates a concrete architecture that conforms to the pattern’s constraints.
Validate an existing architecture against the pattern
calm validate -p patterns/web-app-pattern.json -a architectures/existing-webapp.json
This checks whether the target architecture has the required nodes/relationships and respects the pattern’s constraints.
Watch for placeholders
User-fillable properties are emitted into the generated architecture using placeholder values based on their declared data type:
- String properties use a bracketed token format, e.g., [[ DESCRIPTION ]]
- Integer properties use a sentinel numeric value, e.g., -1
These placeholders act as markers and must be replaced with appropriate architecture-specific values before use.