# Resource Registry — Data Representation (Schemas)

## Context Representation

Contexts represent isolated multi-tenant environments (Venn diagrams) within the infrastructure. They are structured hierarchically, which dictates boundaries for cascading configurations and instance sharing.

### Example: Context Hierarchy

The JSON representation of a single Context explicitly includes its hierarchy, encapsulating `parent` and `children` Contexts as nested objects. When requesting a specific **`HTTP resource`** for a Context, the system serializes these logical boundaries.

```json
{
    "type": "Context",
    "id": "4eb849d5-efbb-4430-9eb6-1968123921b4",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:46:39.330 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:46:39.330 +0000"
    },
    "name": "gcube",
    "path": "/gcube",
    "previousPaths": [],
    "state": "active",
    "effectiveState": "active",
    "parent": null,
    "children": [
        {
            "type": "Context",
            "id": "a7bc333f-84df-498d-ae9d-748b358267b5",
            "name": "devsec",
            "path": "/gcube/devsec",
            "state": "active",
            "effectiveState": "active"
        }
    ]
}
```

#### Field Explanations

```eval_rst
- ``type``: The literal string identifying the schema. In this case, **Context**.
- ``id``: The unique system-managed identifier for this specific Context. *(REST Profile Note: While the abstract IS-Model allows for implementation-specific ID formats, the REST API strictly mandates the use of UUIDs for all ``id`` fields to guarantee global uniqueness and predictable addressing across the federated graph).*
- ``metadata``: An embedded field of type **``Metadata``** handling provenance tracking. It contains:
  - ``createdBy`` (String): The principal who created the Context representation. *(Note: To comply with privacy policies, this field may be returned as ``"[REDACTED]"`` depending on the caller's authorization role).*
  - ``creationTime`` (Date): Creation time.
  - ``lastUpdateBy`` (String): The principal who last updated the instance. *(Note: To comply with privacy policies, this field may be returned as ``"[REDACTED]"`` depending on the caller's authorization role).*
  - ``lastUpdateTime`` (Date): Last Update time.
- ``name``: A simple string defining the descriptive name of the Context. Must consist of alphanumeric characters, dashes, underscores, and dots (matching pattern ``^(?!.*[._-]{2})[a-zA-Z0-9]([a-zA-Z0-9_.-]*[a-zA-Z0-9])?$``). It must start and end with an alphanumeric character, and cannot contain consecutive symbols (such as ``__``, ``--``, or ``..``). Special characters like ``/`` (slash) or spaces are strictly forbidden.
- ``path``: The absolute hierarchical path of the Context from the Root down to the current node (e.g., ``/gcube/devsec/devVRE``). Read-only — clients cannot set or modify this field. It changes only when the Context's ``name`` or ``parent`` is changed (rename / reparent operations); the paths of all descendant Contexts change in the same atomic operation.
- ``previousPaths``: The ordered set of former ``path`` values that still resolve to this Context. It is always present in a standard Context representation, including as an empty array. Across live Contexts, a path string may be owned only once, either as a current ``path`` or as a retained ``previousPaths`` entry. Values do not expire automatically and can be replaced or cleared only through the tracked-update endpoint. A newly established current path—through creation, rename, reparent, or descendant recomputation—removes the same value from every retained set, while an explicit historical-path addition that conflicts with another live owner returns ``409 Conflict``. This field is not included in compact ``parent`` or ``children`` summaries.
- ``state``: The physical operational state of the Context, as configured locally by an administrator. Allowed values: ``active``, ``suspended``, ``created``, ``deleted``.
- ``effectiveState``: A read-only field that reflects the true operational state of the Context by evaluating its ascendance. For example, ``effectiveState`` yields ``suspended`` if the local ``state`` is ``active`` while an ancestor state is ``suspended``. Operations within the Context are strictly governed by this value. It changes only when the Context's own ``state`` or an ancestor's ``state`` is changed; the ``effectiveState`` of all descendant Contexts changes in the same atomic operation. (See the *State Evaluation Matrix* in the [API Authorization Reference](08-api-contexts-and-types.md#inherited-operational-state-effectivestate) for all cases).
- ``parent``: If this Context is a child, it contains the nested representation of its parent Context. The root Context explicitly specifies ``null``. *(Note: To prevent infinite recursion and reduce payload bloat during serialization, nested Context representations within ``parent`` and ``children`` fields act as depth-limited summaries. These summaries are stripped down to the essential fields (``type``, ``id``, ``name``, ``path``, ``state``, ``effectiveState``), intentionally omitting their own ``parent`` and ``children`` fields as well as ``metadata`` and ``history``).*
- ``children``: An array of nested objects representing the immediate child Contexts. Leaf Contexts explicitly return an empty array. In this example, the ``gcube`` Context has a child ``devsec`` Context, forming the hierarchy.
```

Normal Context representations use the stable property order `type`, `id`, `metadata` (when requested), `name`, `path`, `previousPaths`, `state`, `effectiveState`, `parent`, `children`. The `history` property is never included in these representations and is available only through the dedicated Context history endpoint.

## Type Schema Representation (Self-Describing API)

Because the Information System exposes its own schema definitions, clients can dynamically discover how to interact with new instances without requiring out-of-band documentation. The IS-Model relies on 5 public extensible base Types: **Resource**, **Facet**, **IsRelatedTo**, **ConsistsOf**, and **`Property`**. 

The `type` field in the schema definition explicitly declares the structural category of the schema (e.g., `"type": "ResourceSchema"` indicates it defines the blueprint for a **Resource** instance, while `"type": "FacetSchema"` indicates it defines a **Facet** instance). The actual inheritance lineage is declared separately via the `extendedTypes` array.

### Resource Type Schema

A **Resource** schema declares cardinality-constrained **ConsistsOf** and target **Facet** pairings for its instances, and documents which other **Resource** types are expected to be related to it. Pairings omitted from the schema remain valid under the Open-World Assumption. `ResourceSchema` does not expose or accept a `properties` member: descriptive data belongs to **Facet** instances, while the **Resource** schema defines topology. Supplying `properties`, including an empty array, is an invalid Resource schema representation and returns `400 Bad Request`.

```json
{
    "type": "ResourceSchema",
    "id": "e5680fc8-5590-41ab-9d3f-b7e1556d1338",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:23:26.890 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:23:26.890 +0000"
    },
    "name": "EService",
    "description": "EService is any running service that is registered in the infrastructure...",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Service"],
    "consistsOf": [
        {
            "source": "EService",
            "relation": "IsIdentifiedBy",
            "target": "SoftwareFacet",
            "description": "The main software enabling the EService capabilities.",
            "min": 1,
            "max": 1
        },
        {
            "source": "EService",
            "relation": "ConsistsOf",
            "target": "AccessPointFacet",
            "description": "Identify the endpoints of the EService.",
            "min": 1
        }
    ],
    "isRelatedTo": [
        {
            "source": "EService",
            "relation": "Uses",
            "target": "EService",
            "description": "A reference to any other EService the EService instance is invoking.",
            "min": 0
        },
        {
            "source": "HostingNode",
            "relation": "Hosts",
            "target": "EService",
            "description": "An advisory constraint: EServices running inside a SmartGears container should be hosted by 1 and only one HostingNode. Since not all EServices are deployed in this manner, this is treated as an advisory guideline.",
            "min": 1,
            "max": 1
        }
    ]
}
```

#### Field Explanations

```eval_rst
- ``type``: Declares the schema category. ``"ResourceSchema"`` means this schema defines a **Resource**.
- ``id``: The unique identifier for this schema definition.
- ``metadata``: Provenance and tracking metadata for the schema itself.
- ``name``: The formal name of the Type (e.g., **EService**).
- ``description``: The human-readable description of what this Type represents.
- ``version`` & ``changelog``: Track the evolutionary history of the schema. Both are mandatory. ``version`` has the form ``major.minor.patch`` and matches ``^[1-9][0-9]*\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$``; ``changelog`` maps each version to a non-empty description of its change, and ``version`` must be its highest entry. A definition that violates these rules returns ``400 Bad Request``.
- ``abstract``: If ``true``, you cannot create a direct instance of this Type (it only exists to be inherited from). If ``false`` (like **EService**), concrete instances can be created. *(Note: A Type cannot be simultaneously ``abstract: true`` and ``final: true``).*
- ``final``: If ``true``, this Type cannot be further extended by other Types.
- ``locked``: If ``true``, this Type belongs to the Information System model itself and its definition is served read-only: a ``PUT`` that would change it, and any ``DELETE``, return ``409 Conflict``; an identical resubmission is the usual ``200 OK`` no-op. The server assigns this field; a value supplied in a write payload is ignored and does not take part in the comparison.
- ``extendedTypes``: A list of the **direct** parent Types this schema inherits from (e.g., **EService** directly extends **Service**). Through polymorphism, the defined Type inherits all structural constraints of its direct parents, which in turn transitively inherit the constraints of all their ancestors.
- ``consistsOf``: Declares **ConsistsOf** Type and target **Facet** Type pairings whose cardinality (``min``/``max``) the backend enforces. A ``min: n`` means that at least :math:`n` concrete **ConsistsOf** instances (of the specified Type or its subtypes) pointing to **Facet** instances (of the specified Type or its subtypes) must necessarily exist on the **Resource** instance. Conversely, ``max: m`` enforces that at most :math:`m` such instances can exist; an absent ``max`` means no upper bound, and ``min: 0``, or an absent ``min``, no lower one. Undeclared pairings remain valid under the Open-World Assumption and carry no schema cardinality constraint. Both ``consistsOf`` and ``isRelatedTo`` are always present, empty when the Type declares no pairing. *(Note: The dictated **ConsistsOf** or **Facet** Type can be an abstract Type. Thanks to polymorphism, this simply means any concrete instance of their subtypes is structurally valid).* For the strict polymorphic evaluation rules of these pairings, see [Resource Structural Cardinality](03-is-model-core-topology.md#resource-structural-cardinality).
- ``isRelatedTo``: Documents **IsRelatedTo** Type and target **Resource** Type pairings linked to this **Resource** instance (including outbound and inbound relation signatures from the schema owner's perspective), along with advisory cardinality (``min``/``max``). These declarations are not an allowlist: undeclared pairings remain valid. Unlike **ConsistsOf** constraints, **IsRelatedTo** cardinalities are purely **advisory constraints** (First-Class Documentation), never hard backend validation rules. Rigidly forcing the Infrastructure Topology would contradict the Open-World Extensibility Paradigm of the system. The dictated **IsRelatedTo** or **Resource** Type can be abstract; concrete subtypes remain structurally valid. For the polymorphic interpretation of these pairings, see [Resource Structural Cardinality](03-is-model-core-topology.md#resource-structural-cardinality).
  - > **Architectural Note on Dual Perspective Cardinality:** The ``min`` and ``max`` constraints in ``isRelatedTo`` evaluate cardinality from the perspective of the schema owner. In the example above (defined within the **EService** schema), ``min: 1`` and ``max: 1`` mean that *this* specific **EService** instance should have exactly one **Hosts** relation pointing to it from a **HostingNode**. Conversely, the schema definition for **HostingNode** would contain the exact same topological signature, but its cardinalities would be evaluated from its own perspective (e.g., ``min: 1`` and no ``max``), meaning a single **HostingNode** can host an unlimited number of **EService** instances, and it is advised to host at least one (since an empty node serves no business purpose).
```

### Facet Type Schema

A **Facet** schema defines a data structure by specifying a set of custom fields (either primitive fields or complex **`Property`** types) that characterize an aspect of a **Resource** instance.

```json
{
    "type": "FacetSchema",
    "id": "0c0ebac7-ee9b-4325-bedd-c89ff52e6cf2",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:20:56.606 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:20:56.606 +0000"
    },
    "name": "SoftwareFacet",
    "description": "SoftwareFacet captures information on any software associated with the resource.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Facet"],
    "properties": [
        {
            "name": "group",
            "description": "The name of 'group' the software artifact belongs to, e.g., groupId in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "name",
            "description": "The name of the software artifact being described, e.g., artifactId in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "version",
            "description": "The particular release of the software artifact, e.g., version in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "optional",
            "description": "Used to indicate the software optionality...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "Boolean"
        },
        {
            "name": "qualifier",
            "description": "A qualifier for the software, e.g., packaging or scope in maven coordinates...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "description",
            "description": "A human oriented description of the software artifact being described.",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        }
    ]
}
```

#### Field Explanations

- `type`: Declares the schema category. `"FacetSchema"` means this schema defines a **Facet** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields sharing identical semantics with the **Resource** schema.
- `properties`: An array defining the exact structural requirements for the data fields that a **Facet** instance of this Type will hold. Each element is a property definition with exactly these members: `name`, `description`, `mandatory`, `readonly`, `propertyType` (e.g., `String`, `Integer`, or a complex **`Property`** Type), `min`, `max`, `regexp`, and `defaultValue`. Since a Type definition is closed, any other member returns `400 Bad Request`. *(Note on Constraints: a `readonly` field is set when the instance is created and cannot be changed afterwards: a `PUT` or `PATCH` that would change its value returns `409 Conflict`. A `mandatory` field MUST be present with a non-`null` value; when a full representation (`POST`, `PUT`) omits it, the server sets it to the property's declared `defaultValue`, and rejects the request with `409 Conflict` when no `defaultValue` is declared. An optional one may be omitted. In a full representation (`POST`, `PUT`) an explicit `null` means the same as an omitted field, at any depth, so no separate constraint on `null` exists; in a `PATCH`, an omitted property is left unchanged and `null` removes it. An empty `regexp` means no pattern; an absent `min` or `max` means no bound).* See [Elimination of `notnull`](12-is-architectural-decisions.html#elimination-of-notnull-as-an-independent-property-constraint).

#### Property Naming Constraints (Normative)

To ensure robust parsing, prevent HTTP Header Injection vulnerabilities (such as when rendering `X-Warning` headers), and avoid namespace collisions with internal query semantics, the names of all properties (whether statically declared in the schema via the `properties` array or dynamically injected via Schema-Mixed Mode) **MUST strictly adhere to the following regular expression:**

```regex
^[a-zA-Z][a-zA-Z0-9_-]*$
```
```eval_rst
In plain English, this dictates that:
- The **first character** must always be an unaccented ASCII letter (uppercase ``A-Z`` or lowercase ``a-z``).
- **Subsequent characters** can be unaccented ASCII letters, digits (``0-9``), underscores (``_``), or hyphens (``-``).
- *(Note: The ``^`` and \$ symbols in the expression above are standard regex anchors representing the strict start and end of the string, they are not allowed characters within the name itself).*
```

```eval_rst
By establishing this pattern, this universal rule explicitly forbids:
1. **System/Query prefixes:** Property names starting with ``@`` or ``_``.
2. **Special/Unicode characters:** Blank spaces, accented letters (e.g., ``à``, ``è``), or currency symbols (e.g., ``€``, \$).
3. **Delimiter/Control characters:** Characters such as ``\r``, ``\n``, ``,``, ``;``, ``=``, or ``"``.
4. **System field names:** ``type``, ``supertypes``, ``id``, ``metadata``, and ``contexts`` are reserved for system fields and cannot name a property; a **Relation** Type cannot redefine ``propagationConstraint``. ``type`` in particular is globally reserved by the system. In a dynamic and hierarchical model, this field is fundamentally required to recognize the exact schema type of an object. This explicit recognition subsequently enables polymorphic deserialization and dynamic class instantiation. It is strictly forbidden to use it as a custom property name anywhere in the payload.
```

Property names that violate these constraints are not valid IS-Model fields. Any attempt to register a new Type Schema defining an invalid property name will be strictly rejected with a `400 Bad Request`. *(Note: The behavior when encountering invalid property names dynamically injected into instances is governed by the lenient payload processing rules detailed in the REST API Foundations chapter).*

### IsRelatedTo Type Schema

An **IsRelatedTo** schema dictates the exact allowed source **Resource** type and target **Resource** type for its **Relation** instances.

```json
{
    "type": "IsRelatedToSchema",
    "id": "bc8e6b37-5c90-4bcf-be89-3db3792b168b",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:24:13.041 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:24:13.041 +0000"
    },
    "name": "Uses",
    "description": "The Uses relation indicates that the source EService invokes the target EService. It specializes the semantics of CallsFor.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": [ "CallsFor" ],
    "source": "EService",
    "target": "EService",
    "properties": []
}
```

#### Field Explanations

- `type`: Declares the schema category. `"IsRelatedToSchema"` means this schema defines an **IsRelatedTo** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `source`: Strictly dictates the allowed Type for the **Resource** instance acting as the source.
- `target`: Strictly dictates the allowed Type for the **Resource** instance acting as the target.
- `properties`: An array defining any custom property fields associated with **IsRelatedTo** instances of this Type (using the same strict structure and constraints as the `properties` array in a **Facet** or **`Property`** schema).

### ConsistsOf Type Schema

A **ConsistsOf** schema dictates the allowed source **Resource** type and target **Facet** type for its **Relation** instances.

```json
{
    "type": "ConsistsOfSchema",
    "id": "fda4eb23-0d84-4364-a976-8ff0565043f0",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:24:53.292 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:24:53.292 +0000"
    },
    "name": "HasContact",
    "description": "HasContact is a base relation type to capture the diverse points of contact associated with a resource.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": true,
    "final": false,
    "extendedTypes": ["ConsistsOf"],
    "source": "Resource",
    "target": "ContactFacet",
    "properties": []
}
```

#### Field Explanations

- `type`: Declares the schema category. `"ConsistsOfSchema"` means this schema defines a **ConsistsOf** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `source`: Dictates the allowed **Resource** type.
- `target`: Dictates the allowed **Facet** type that can be attached.
- `properties`: An array defining any custom property fields associated with **ConsistsOf** instances of this Type (using the same strict structure and constraints as the `properties` array in a **Facet** or **`Property`** schema).

### Property Type Schema

A **`Property`** schema defines a complex data structure that can be embedded directly within a **Facet** instance or **Relation** instance. It does not have an independent graph ID.

```json
{
    "type": "PropertySchema",
    "id": "369e3c7f-b490-43b9-b924-c13aad63bf77",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:19:38.008 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:19:38.008 +0000"
    },
    "name": "Event",
    "description": "This type provides information regarding an event using the Five Ws (checklist) https://en.wikipedia.org/wiki/Five_Ws + How",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Property"],
    "properties": [
        {
            "name": "who",
            "description": "WHO triggered the event.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "what",
            "description": "WHAT happened.",
            "mandatory": true,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "when",
            "description": "WHEN the event occurred. It is represented in the format yyyy-MM-dd HH:mm:ss.SSS Z.",
            "mandatory": true,
            "readonly": true,
            "regexp": "",
            "propertyType": "Date"
        },
        {
            "name": "where",
            "description": "The location (can be virtual) WHERE the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "why",
            "description": "The reason WHY the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "how",
            "description": "How the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        }
    ]
}
```

#### Field Explanations

- `type`: Declares the schema category. `"PropertySchema"` means this schema defines a **`Property`** block.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `properties`: Defines the specific nested fields (e.g., `who`, `what`, `when`, `where`, `why` and `how`) that compose this reusable complex block (like **`Event`**).
