Skip to main content

Metamodel JSON

What is a Metamodel?

The Concerto metamodel is the schema that defines the structure of all valid Concerto models. It describes the types and relationships that can be used to build domain models.

When you parse a CTO file, Concerto creates an AST (Abstract Syntax Tree), also known as a metamodel instance. This is a runtime object representation that is an instance of the metamodel—it captures the complete structure of your specific model including namespaces, declarations, properties, and relationships.

This AST/metamodel instance can be represented in two formats:

  • CTO format: The human-readable text format you write (e.g., concept Person { o String name })
  • JSON format: A structured JSON representation of the same AST/metamodel instance

Both formats represent the same underlying model instance. The JSON format is particularly useful when working with Concerto APIs programmatically, while CTO is easier for humans to read and write.

Interactive Explorer

Explore how the same AST/metamodel instance is represented in both CTO and JSON formats:

Interactive Metamodel Explorer

Edit the CTO on the left and click "Parse to Metamodel" to see how it converts to JSON. Or edit the JSON on the right and click "Print to CTO" to convert back.

CTO Model

namespace example@1.0.0

concept Person {
  o String firstName
  o String lastName
  o String email
}

concept Address {
  o String street
  o String city
  o String country
  o String postalCode
}

Metamodel JSON

{
  "$class": "concerto.metamodel@1.0.0.Model",
  "decorators": [],
  "namespace": "example@1.0.0",
  "imports": [],
  "declarations": [
    {
      "$class": "concerto.metamodel@1.0.0.ConceptDeclaration",
      "name": "Person",
      "isAbstract": false,
      "properties": [
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "firstName",
          "isArray": false,
          "isOptional": false
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "lastName",
          "isArray": false,
          "isOptional": false
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "email",
          "isArray": false,
          "isOptional": false
        }
      ]
    },
    {
      "$class": "concerto.metamodel@1.0.0.ConceptDeclaration",
      "name": "Address",
      "isAbstract": false,
      "properties": [
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "street",
          "isArray": false,
          "isOptional": false
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "city",
          "isArray": false,
          "isOptional": false
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "country",
          "isArray": false,
          "isOptional": false
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "postalCode",
          "isArray": false,
          "isOptional": false
        }
      ]
    }
  ]
}
✓ Valid JSON

Examples to Try

Simple Concept
View Example
CTO:
namespace shop@1.0.0

concept Product {
  o String name
  o Number price
}
Metamodel:
{
  "$class": "concerto.metamodel@1.0.0.Model",
  "namespace": "shop@1.0.0",
  "declarations": [
    {
      "$class": "concerto.metamodel@1.0.0.ConceptDeclaration",
      "name": "Product",
      "properties": [
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "name"
        },
        {
          "$class": "concerto.metamodel@1.0.0.NumberProperty",
          "name": "price"
        }
      ]
    }
  ]
}
Enumeration
View Example
CTO:
namespace order@1.0.0

enum Status {
  o PENDING
  o SHIPPED
  o DELIVERED
}
Metamodel:
{
  "$class": "concerto.metamodel@1.0.0.Model",
  "namespace": "order@1.0.0",
  "declarations": [
    {
      "$class": "concerto.metamodel@1.0.0.EnumDeclaration",
      "name": "Status",
      "properties": [
        {
          "$class": "concerto.metamodel@1.0.0.EnumValueDeclaration",
          "name": "PENDING"
        },
        {
          "$class": "concerto.metamodel@1.0.0.EnumValueDeclaration",
          "name": "SHIPPED"
        },
        {
          "$class": "concerto.metamodel@1.0.0.EnumValueDeclaration",
          "name": "DELIVERED"
        }
      ]
    }
  ]
}
Optional and Array Properties
View Example
CTO:
namespace contact@1.0.0

concept Person {
  o String name
  o String[] emails
  o String phone optional
}
Metamodel:
{
  "$class": "concerto.metamodel@1.0.0.Model",
  "namespace": "contact@1.0.0",
  "declarations": [
    {
      "$class": "concerto.metamodel@1.0.0.ConceptDeclaration",
      "name": "Person",
      "properties": [
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "name"
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "emails",
          "isArray": true
        },
        {
          "$class": "concerto.metamodel@1.0.0.StringProperty",
          "name": "phone",
          "isOptional": true
        }
      ]
    }
  ]
}

Converting with the CLI

Convert between CTO and JSON representations of your AST/metamodel instance using the Concerto CLI:

Parse CTO to JSON (creates an AST/metamodel instance):

concerto parse --model mymodel.cto --excludeLineLocations

Convert JSON to CTO (creates CTO from an AST/metamodel instance):

concerto print --input mymodel.json

The $class property identifies each object's type within the AST. Properties include isArray and isOptional flags that correspond to the CTO syntax.

Reference

For a complete definition of all metamodel classes and properties, see the Concerto metamodel reference.