# Defining your schema

[Schemas](https://developer.mediarithmics.io/schema) are associated with [datamarts](https://developer.mediarithmics.io/communities-and-organisations/datamart) by managing objects with the following properties:&#x20;

{% hint style="success" %}
Make sure you learned about [schema's concepts and how they are structured](https://developer.mediarithmics.io/schema).
{% endhint %}

```javascript
// DRAFT Schema
{
    "id": "1385",
    "datamart_id": "1509",
    "status": "DRAFT",
    "creation_date": 1609888013947,
    "last_modification_date": 1610443926552,
    "publication_date": null,
    "suspension_date": null
}

// LIVE Schema
{
    "id": "1281",
    "datamart_id": "1509",
    "status": "LIVE",
    "creation_date": 1603198414771,
    "last_modification_date": 1603198415117,
    "publication_date": 1603198415733,
    "suspension_date": null
}
        
// ARCHIVED Schema
{
    "id": "1276",
    "datamart_id": "1509",
    "status": "ARCHIVED",
    "creation_date": 1603102827888,
    "last_modification_date": 1603102828087,
    "publication_date": 1603102828479,
    "suspension_date": 1603102848269
}
```

## Schema publication workflow

The process for publishing a schema is as follows:

1. Create a new schema definition
2. Upload the schema associated with the definition
3. Validate the schema
4. Publish the schema

## Schema updates

After updating a schema, you can immediately use all its properties into the `select` part of your [OTQL queries](https://developer.mediarithmics.io/querying-your-data/otql-queries) and any operator that doesn't require indexing.

If you add a new indexed property, only new elements going into your datamart will be indexed. You will be able to run `WHERE` queries and operators needing indexing, but your queries will not return values for elements already in your datamart. You can add a new indexed property by either adding a new property with [@TreeIndex directive](https://developer.mediarithmics.io/schema/..#treeindex) or adding the @TreeIndex directive to an existing property.

If you remove an indexed property, you will instantly stop being able to run `WHERE` queries and operators needing indexing for this query.

{% hint style="success" %}
You can ask your mediarithmics contact to start a complete reindexing of your datamart if required
{% endhint %}

## Manage schemas with mics CLI

You can use the [MICS CLI](https://developer.mediarithmics.io/resources/tools-and-libraries/mics-cli) to power up your schema definitions workflow.&#x20;

### Download a schema

Retrieve the LIVE schema or the specified one for a given datamart, and save it as a `.gql` file named `schema-<DATAMARTID>-<SCHEMAID>.gql`.

Use it to download the schema you want to start with, usually the current LIVE version.

```
USAGE
  $ mics-cli schema:fetch DATAMARTID [SCHEMAID]

ARGUMENTS
  DATAMARTID  the ID of the datamart
  SCHEMAID    [default: LIVE] the ID of the schema, or LIVE to get the live schema

OPTIONS
  --stdout  output the content of the file instead of saving it in a file
```

![](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MQrOpiCDrITvBrNBllx%2F-MQrPw_Ghbuk-qCyjzzo%2Fimage.png?alt=media\&token=7be5c1b7-ed3e-43b9-8b45-8b194109838e)

If you want to show the schema in the output, use the `--stdout` flag.

<div align="center"><img src="https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MQrOpiCDrITvBrNBllx%2F-MQrQKR2LrCyaFd_NW7b%2Fimage.png?alt=media&#x26;token=20832cae-b2a7-4e63-b79f-4d02e07a1d97" alt=""></div>

### Update a schema

Create a draft, upload a file, validate it, and publish the schema with this all-in-one command.&#x20;

Automatically handles status and [cloning best practices](#create-a-draft-by-cloning):&#x20;

* If a draft schema already exists, update it before publishing.
* Latest LIVE schema is cloned, if available, and `--noClone` flag is not set

You can keep your schema as a DRAFT and not publish it using  the `--skipPublish`flag.&#x20;

<div align="left"><img src="https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MRKlDK69wtz_oO0vU0u%2F-MRKrpVbsvYNn-e_XWVn%2Fimage.png?alt=media&#x26;token=d9912424-a351-448c-9b70-db0ecb41e7e5" alt=""></div>

<div align="left"><img src="https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MRKlDK69wtz_oO0vU0u%2F-MRKs51VTFgm64CSupzG%2Fimage.png?alt=media&#x26;token=ebcb1ee5-3477-420a-9e80-91ca6a71d73a" alt=""></div>

## Get existing schemas

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas`

Returns all schemas and their status.

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |

{% tabs %}
{% tab title="200 " %}

```
{
    "status": "ok",
    "data": [
        {
            "id": "1266",
            "datamart_id": "1509",
            "status": "ARCHIVED",
            "creation_date": 1602860201358,
            "last_modification_date": 1602860221562,
            "publication_date": 1602860275189,
            "suspension_date": 1602860362588
        },
        {
            "id": "1281",
            "datamart_id": "1509",
            "status": "LIVE",
            "creation_date": 1603198414771,
            "last_modification_date": 1603198415117,
            "publication_date": 1603198415733,
            "suspension_date": null
        },
        {
            "id": "1385",
            "datamart_id": "1509",
            "status": "DRAFT",
            "creation_date": 1609888013947,
            "last_modification_date": 1610443926552,
            "publication_date": null,
            "suspension_date": null
        }
    ],
    "count": 3,
    "total": 3,
    "first_result": 0,
    "max_result": 2147483647,
    "max_results": 2147483647
}
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
Archived schemas are displayed, meaning you can watch your history
{% endhint %}

## Get a schema

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId`

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |
| schemaId   | integer | The ID of the schema   |

{% tabs %}
{% tab title="200 " %}

```
{
    "status": "ok",
    "data": {
        "id": "1266",
        "datamart_id": "1509",
        "status": "ARCHIVED",
        "creation_date": 1602860201358,
        "last_modification_date": 1602860221562,
        "publication_date": 1602860275189,
        "suspension_date": 1602860362588
    }
}
```

{% endtab %}
{% endtabs %}

## Get the content of a schema

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId/text`

Allows you to visualize how your schema is in the current version, or how it has been in archived versions

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | string  | The ID of the datamart |
| schemaId   | integer | The ID of the schema   |

{% tabs %}
{% tab title="200 " %}

```
##


type UserPoint  @TreeIndexRoot(index:"USER_INDEX") {
   events:[ActivityEvent!]!
   creation_ts:Timestamp! @TreeIndex(index:"USER_INDEX")
   id:ID!
}

##


type ActivityEvent  {
   referrer:String @TreeIndex(index:"USER_INDEX") @Property(path:"$properties.$referrer")
   url:String @TreeIndex(index:"USER_INDEX") @Property(path:"$properties.$url")
   date:Date! @TreeIndex(index:"USER_INDEX") @Function(params:["ts"], name:"ISODate")
   nature:String @Property(path:"$event_name") @TreeIndex(index:"USER_INDEX")
   ts:Timestamp!
   id:ID!
}


```

{% endtab %}
{% endtabs %}

## Create a DRAFT by cloning

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId/clone`

Creates a new DRAFT schema if there's no existing one, by cloning an existing one.

#### Path Parameters

| Name       | Type    | Description                                                      |
| ---------- | ------- | ---------------------------------------------------------------- |
| schemaId   | integer | The ID of the schema to clone. Usually the current LIVE version. |
| datamartId | integer | The ID of the datamart                                           |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "status": "ok",
    "data": {
        "id": "1395",
        "datamart_id": "1509",
        "status": "DRAFT",
        "creation_date": 1610449867207,
        "last_modification_date": 1610449867207,
        "publication_date": null,
        "suspension_date": null
    }
}
```

{% endtab %}

{% tab title="400 If you try to create a new schema while there's already one draft" %}

```javascript
{
    "status": "error",
    "error": "Impossible to create a new schema, there is already one draft schema",
    "error_code": "CONSTRAINT_VIOLATION_EXCEPTION",
    "error_id": "690596a9-b0e0-43b3-88e8-b90d08b98029"
}
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
This is the preferred method to create a DRAFT schema, as it will keep all settings from the previous version, like cluster versions, and index sizes.
{% endhint %}

## Create a DRAFT without cloning

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas`

Creates a new DRAFT schema if there's no existing one without cloning.

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "status": "ok",
    "data": {
        "id": "1395",
        "datamart_id": "1509",
        "status": "DRAFT",
        "creation_date": 1610449867207,
        "last_modification_date": 1610449867207,
        "publication_date": null,
        "suspension_date": null
    }
}
```

{% endtab %}

{% tab title="400 If you try to create a new schema while there's already one draft" %}

```javascript
{
    "status": "error",
    "error": "Impossible to create a new schema, there is already one draft schema",
    "error_code": "CONSTRAINT_VIOLATION_EXCEPTION",
    "error_id": "690596a9-b0e0-43b3-88e8-b90d08b98029"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
For the schema to keep initial settings—for example, elastic search version, and index size—you need to clone the previous LIVE version. Only use this endpoint if you know the required settings and you can set them up before publishing.
{% endhint %}

## Upload the content

<mark style="color:orange;">`PUT`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId/text`

Add the schema to content to the raw body of the request

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |
| schemaId   | integer | The ID of the schema   |

#### Request Body

| Name | Type   | Description          |
| ---- | ------ | -------------------- |
| body | string | Raw schema to upload |

{% tabs %}
{% tab title="200 " %}

```
{
    "status": "ok"
}
```

{% endtab %}
{% endtabs %}

## Validate a DRAFT schema

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId/validation`

Tells you if the uploaded schema is valid, and shows errors if there are any.

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |
| schemaId   | integer | The ID of the schema   |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "status": "ok",
    "data": {
        "datamart_id": "1509",
        "schema_id": "1266",
        "tree_index_operations": [
            {
                "datamart_id": "1509",
                "index_selection_id": "2121",
                "index_name": "USER_INDEX",
                "init_strategy": "FORCE_NO_BUILD",
                "driver_version_major_number": 1,
                "driver_version_minor_number": 2,
                "current_index_id": "574",
                "current_index_size": "SMALL",
                "new_index": false,
                "new_index_size": "SMALL",
                "init_job": null,
                "error_code": null,
                "error_message": null
            }
        ],
        "schema_errors": []
    }
}
```

{% endtab %}

{% tab title="400 If there are validation errors" %}

```javascript
{
    "status": "error",
    "error": "2 error(s) found when validating schema : Type 'UserPoint' which is root of tree index 'USER_INDEX' requires a scalar field named 'creation_ts' to be annotated with '@TreeIndex(index:\"USER_INDEX\")' and to be typed 'Timestamp!', Type 'UserAccount' which is root of tree index 'USER_INDEX' requires a scalar field named 'compartment_id' to be annotated with '@TreeIndex(index:\"USER_INDEX\")' and to be typed 'String!'",
    "error_code": "BAD_REQUEST_DATA",
    "error_id": "6a52cea9-6de4-40f5-972e-a8480c268d19"
}
```

{% endtab %}
{% endtabs %}

## Publish a schema

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/graphdb_runtime_schemas/:schemaId/publication`

The selected schema goes LIVE, and the actual LIVE schema is ARCHIVED. Will show an error if you didn't validate the schema.

#### Path Parameters

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| datamartId | integer | The ID of the datamart |
| schemaId   | integer | The ID of the datamart |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "status": "ok",
    "data": {
        "datamart_id": "1509",
        "schema_id": "1395",
        "tree_indices": [
            {
                "index_name": "USER_INDEX",
                "new_index": false,
                "index_id": "574",
                "index_size": "SMALL",
                "init_strategy": "FORCE_NO_BUILD",
                "driver_version_major_number": 1,
                "driver_version_minor_number": 2,
                "init_job": null
            }
        ]
    }
}
```

{% endtab %}

{% tab title="400 If the schema has not been validated" %}

```javascript
{
    "status": "error",
    "error": "Impossible to publish schema, validate the schema before a new publication",
    "error_code": "BAD_REQUEST_DATA",
    "error_id": "76e70020-02cb-40ec-8109-adf204aa0a7b"
}
```

{% endtab %}
{% endtabs %}
