Skip to content

2. Creating a Data Schema

Using our Data Development Kit (DDK), you can configure the data schema for your project. This allows you to build one or many data schemas to connect all the data required for your use case and leverage this across any application.

What You'll Learn
  • Create a DDK server and configure database connections
  • Define schema objects (SimSettings and SimOutcome) with fields and constraints
  • Establish relationships between objects using foreign keys
  • Configure resolvers and workflow triggers
  • Build, deploy, and migrate your schema
  • Test your schema using GraphiQL

Before starting, consider the application you want to design and what data needs to be displayed on the front end. This will help you determine which schemas, objects, and fields you need. The following instructions walk you through setting up a data schema for a traffic network simulation.

2.1 Creating a Server

Click on the New Server button to create a server. This server acts as your data schema and is responsible for storing the APIs and resolvers required to manage your data schema effectively.

Create server

Fill out the following information for the Server details section:

  • Server name: Must be all lowercase with no numbers or spaces (e.g., transport)
  • Port: A minimum four-digit number (e.g., 1234)
Server details

Click Next and fill out the following information for the Create new schema section:

  • Schema Name: Must be all lowercase with no numbers or spaces (e.g., transportschema). You can have multiple schemas per server to separate your data objects.
Schema name

Click Next and fill out the following information for the Configure databases section:

  • Alias: postgres
  • Port: 5432
  • Username: postgres
  • Password: postgres
  • Database name: postgres
  • Schema name: public

After filling in all the required fields, click on the Next button.

Configure database

In the Configure Redis step, you can enable or disable Redis based on your needs. Finally, click on Create to create the DDK server.

Redis

Custom code options

Want to see what more complex schemas look like? You can use the code editor tool to copy in some sample schema templates available at this link: Data Schema Code Templates

Alternatively, if you're familiar with GraphQL and have your own schema in mind you can write this out using the custom code editor.

The server has been successfully created, as shown below.

new server has been successfully created

2.2 Configuring Your Schema

Now that the schema has been created, you can define objects relevant to your project. The following instructions will allow you to recreate the OR Demo Project and guide you through the steps required for future projects.

You can define fields in the Types tab. To add each field, simply drag it into the visualiser.

Object

An object is a definition of data records in the system. We are scaffolding the different pieces of data required to build an end-to-end application.

Creating the SimSettings Object

Define the object that will set the inputs for your simulation. We'll call this object SimSettings.

SimSettings

This object will represent setting the geographical location required to simulate a traffic network. The fields required to set the geographical location are: longitude, latitude, and radius.

Create object

Add a new Object Field, then change the object name to SimSettings by clicking the three-dot menu and selecting Edit Metadata.

SimSettings object

The id field is created by default. To configure it:

  1. Click the id field to open its configuration panel
  2. In the DataType tab, mark the field as Required
  3. Under Constraints, enable Primary Key
  4. Click Update to save the changes
ID Primary Key

INFO

This id field is a primary key which acts as a unique identifier for your SimSettings object.

Every object defined in your schema mirrors a table in a database. Think of defining your schema as structuring relational database tables. In this step, you're defining a SimSettings table with a unique identifier column called id.

With the SimSettings object selected, click the + icon to add a new field. Set the Name to longitude. In the DataType tab, click the Field required checkbox and select Float from the Data type dropdown. Click Update.

Add longitude field

INFO

Setting a field as Field required is a way of saying this field must have a data value in its database cell. In this example, longitude must have a float (decimal) value in every row entry in the table.

With the SimSettings object selected, click the + icon to add a new field. Set the Name to latitude. In the DataType tab, click the Field required checkbox and select Float from the Data type dropdown. Click Update.

Add latitude field

With the SimSettings object selected, click the + icon to add a new field. Set the Name to radius. In the DataType tab, click the Field required checkbox and select Int from the Data type dropdown. Set the default value to 10. Click Update.

Add radius field

SimSettings

In this example, the longitude and latitude values represent coordinates, and the radius captures the map radius area from that coordinate location.

SimSettings Fields Summary

Field NameData TypeRequiredConstraintsDefault Value
idIDYesPrimary Key-
longitudeFloatYes--
latitudeFloatYes--
radiusIntYes-10

Creating the SimOutcome Object

Define our second object to store the outcome of your simulation. We'll call this object SimOutcome. Drag Object into the visualiser to create it.

Edit to SimOutcome

Change the object name to SimOutcome.

SimOutcome Object

SimOutcome

This object will represent and store the outcomes of your traffic simulation after it's executed. The fields that the simulation will output are:

  • result: The actual result from the simulation. This stores a mapping of all the vehicle coordinates at a certain time.
  • dtTimestamp: The date-timestamp of a simulation result.
  • simSettingsId: An id that matches a SimSettings record. This is a one-to-one relationship - each SimSettings table matches to a SimOutcome table.

The id field is created by default. To configure it:

  1. Click the id field to open its configuration panel
  2. In the DataType tab, mark the field as Required
  3. Under Constraints, enable Primary Key (this acts as a unique identifier for your SimOutcome object)
  4. Click Update to save the changes
SimOutcome id field

With the SimOutcome object selected, click the + icon to add a new field. Change name to dtTimestamp. In the DataType tab, click the Field required checkbox and select Int from the Data type dropdown. Click Update.

Add dtTimestamp field

INFO

dtTimestamp is a short-hand for date-timestamp. It will store the date timestamp for a set of simulation results. This field is important to be able to view the movement of your traffic network in chronological order.

With the SimOutcome object selected, click the + icon to add a new field. Change name to result. In the DataType tab, click the Field required checkbox and select String from the Data type dropdown. Click Update.

Add result field

With the SimOutcome object selected, click the + icon to add a new field. Change name to simSettingsId. In the DataType tab, click the Field required checkbox and select ID from the Data type dropdown. Click Update.

Add simSettingsId field

This completes the SimOutcome object.

SimOutcome Fields Summary

Field NameData TypeRequiredConstraintsDefault Value
idIDYesPrimary Key-
dtTimestampIntYes--
resultStringYes--
simSettingsIdIDYesUnique-

SimOutcome

This object is responsible for storing the results of each simulation execution. In combination with the result and dtTimestamp fields, we will leverage this object to visualise the results on a map.

Creating the Relationship

Now we'll create a relationship to link our two objects together.

  1. Click back to the SimSettings object and add a new field by clicking the + icon.
  2. Click the new field to open its settings.
  3. Change the name to SimOutcome and click Update.
  4. Go to the DataType tab and configure the following:
    • Mark the field as Required
    • From the Type dropdown, select Existing Object and set the DataType to SimOutcome
    • Set Mapping to One-to-One
    • Set the Foreign Key to simSettingsId
    • Set the Foreign Key Reference to id
  5. Click Update to save the changes.
Create relationship

Foreign key mappings

A foreign key is a database concept that shows the relationship between 2 objects/tables. In our SimOutcome field, we are essentially saying "grab the simSettingsId field from one table and link it to the primary key (id) of the other table".

From a high-level view, this relationship means that every settings input that is passed into a simulation is linked to a specific outcome.

After clicking Update, you should see a link between the two objects as shown below.

Schema relationship view

You can also hover over the link to view more details.

Hover relationship view

This completes the SimSettings object.

Configuring Resolvers

  1. In the SimSettings object, click the Configure icon at the bottom of the node to open the configuration panel.
Configuration Simsettings
  1. In the Basic tab, ensure all options are checked: Create, Read, Update, Delete.

Resolver

A resolver is essentially a function in a DDK server on how to fetch/modify data of an object.

Linking it to a database table, there are four default resolvers:

  • create: Creates a new row entry in a database table with data for an object.
  • read: Reads/fetches a row entry or list of entries from a database table for an object.
  • update: Updates specific fields in a row entry of a database table for an object.
  • delete: Deletes a row from a database table for an object.
  1. Go to the Advanced tab, enable Allow workflow trigger operations, and click Update.
Allow workflow trigger operations

Trigger

A trigger is a link to the Modelling Development Kit (MDK) that allows MDK workflows (ie. our traffic simulation) to be executed via an object default resolver.

In other words, we are enabling the option where if a default resolver is executed, it will trigger a deployed simulation workflow from the MDK.

Your final schema should look like this:

Final schema

ORA in the DDK

You can use our Optimal Reality Assistant (ORA) in the DDK. Click the AI icon on the right to install ORA.

ORA Icon

ORA allows you to describe your schema using natural language, and it will generate the code for you.

Chat With ORA

You can then review the code and publish. We won't use ORA in this walkthrough since we need a specific schema setup, but feel free to explore this feature later.

Review and Publish

A Note About Loading Data

This Traffic Simulation example doesn't require pre-loaded data since all data is generated through the simulation. However, here are the options available for loading data when needed.

To attach data, you'll need to install Experiment Manager first (this happens automatically when you open the MDK for the first time).

On a schema object, click the three-dot menu on the right side to access these options:

  • Mock Data Generation: Users can generate mock data for any object in the schema. This data is automatically structured to match the object's fields, so no mapping is required.
  • Data Attachment: Users can attach data to objects by importing CSV files from their local machine or from URLs. The system provides a wizard to map source fields to target object fields, with options to match exactly or skip fields.
Data attachment options

Custom code options

To import data from a file you'll need to use VS Code to upload the relevant file to your local instance. You can access that here: https://web.core.optimalreality.com/code

2.3 Deploying Your Schema

Now that you've configured your schema in section 2.2, it's time to deploy it.

1. Click the Regenerate button in the top center of the screen and wait for it to be successful.

Action Bar

Regeneration

Regeneration is a concept that checks and validates your schema structure.

Save and regenerate

Build and Deploy

2. Click the Build button (hammer icon) to build your DDK server and wait for it to be successful.

Build

Build means that we are packaging your entire DDK server (with your schema) into an asset. This asset is called an image. This image will become crucial in deploying your schema into the local environment. In this process, all the APIs required for the front-end, back-end, and modelling are all auto-generated.

build

3. Go back to the Nexus and within the Container registry panel on the left side, click on the three dots in the transport (or your custom named server) node and select Configure Deployment to confirm/validate the fields.

configure-deployment

You can also click the three-dot menu on the Transport node in the Visualiser and select Configure Deployment.

node configure-deployment

Set the Version Tag to latest, then click Next and Save.

Transport Deploy Step1

INFO

These wizards are prefilled with sensitive defaults and do not need to be changed.

Once complete, go back to the Container registry panel and repeat the same process for the postgres node.

Postgress Deployment step1Postgress Deployment step2

Configuration

This process is setting and saving the configuration of the images. These configurations are displayed by default. We have two images:

  • our DDK transport server, and
  • the postgres database that we configured in section 2.1.

4. Select the Deploy button in the top center.

Deploy button

Select the two images in the pop up.

Configure deployment 2

Click Next, then click Deploy.

Configure deployment 3

5. Wait for your transport node and postgres node to become healthy (green) in Nexus.

Nexus Deploy Finished

Troubleshooting

If, after deployment, the postgres and transport nodes are still not green (healthy), click on the Logs tab on the right panel, check the logs to find the cause of the issue, and if the problem persists, contact OR support.

LOGS

Deployment

Deploying these images into the local environment means we want our DDK transport and postgres microservices to run in the environment.

There's a link between transport and postgres to indicate a database dependency.

Once both microservices are running healthily in Nexus, go back to the DDK.

Creating Migrations

Back in the DDK, we need to migrate the schema to make it available:

6. Click the Migrate button at the top center of your server (e.g. transport).

7. Click on + Create migration. Then Click on Create. This may take a few minutes.

Create migration

Migrations

Data migrations move data between systems, formats, or storage solutions on deployed databases. They ensure integrity, compatibility, and minimal downtime while upgrading, consolidating, or transitioning applications and databases. This involves extraction, transformation, validation, and loading (ETL) processes.

8. Once the migration is created, you'll see the View All Migrations panel (you can also access this panel by clicking the Migrate button and selecting View All). Select latest from the left panel and click the Apply latest button, then wait for it to complete successfully.

INFO

This makes the tables for the data schema, allowing your database to be migrated to the appropriate version of the DDK server.

Apply migration

🎉 Once migration apply is complete, you continue to the Modelling Development Kit!

Follow the instructions in: Building and Configuring Workflows

For more advanced tutorials on GraphiQL and low-code schema development, see below.

2.4 GraphiQL

In the DDK, there is a sub-tool called GraphiQL View. This is the built-in GraphQL interface that allows you to test GraphQL queries and resolvers. You can explore the schema documentation to see the types, objects, and resolvers in your server data schema. Think of it as Postman, but for GraphQL.

To access GraphiQL:

Click the GraphiQL View icon in the second left sidebar while inside the DDK.

GraphiQL View

Schema Documentation

Click on the top left book icon to view the Docs.

This allows you to explore the schema for this GraphQL server. You can discover different types and their fields, as well as available query, mutation, and subscription resolvers, including their arguments and return types. Learn more about the type system here: Schemas and Types | GraphQL

GraphiQL View

Query Editor and Executor

In the middle pane, you can write GraphQL operations for queries and mutations to execute resolvers in the server.

For example, you may wish to send a mutation to create a sim settings object:

graphql
mutation createSimSettings {
  createSimSettings(
    id: "id_1"
    longitude: 144.946457
    latitude: -37.840935
    radius: 10
  ) {
    id
    longitude
    latitude
    radius
  }
}

Copy the operation above and execute it using the play icon (or Cmd/Ctrl + Enter on selected cursor).

GraphiQL mutation

Then for example, you may wish to query for the current sim settings objects in the DB:

graphql
query getSimSettingsList {
  getSimSettingsList {
    id
    longitude
    latitude
    radius
  }
}

Copy the operation above and execute it using the play icon (or Cmd/Ctrl + Enter on selected cursor).

GraphiQL query

This is a useful tool for testing your auto-generated GraphQL schema and resolvers before integrating with MDK workflows or FDK components.

2.5 Low Code Options

Low Code Options

To view and edit the code directly, click the Code View button </> Code to see the generated code. You can edit or add objects through here, but the schema must follow a specific format to save successfully.

Code view button
Code view editor

Custom Code Options

To import a schema you've created elsewhere, or write one from scratch, click the Code View button </> Code in the top center-right of the panel. Rather than configuring options as we did in section 2.2, you can copy over or write the schema directly in code.

Example from this tutorial:

graphql
type SimSettings @required(type: "CREATE, READ, UPDATE, DELETE", table: "true", trigger: "true") {
    id: ID! @constraint(type: "primarykey")
    longitude: Float!
    latitude: Float!
    radius: Int! @constraint(type: "default", value: "10")
    simOutcome: SimOutcome! @mapping(type: "one2one", foreignKey: "simSettingsId", foreignKeyReference: "id")
}

type SimOutcome @required(type: "CREATE, READ, UPDATE, DELETE", table: "true") {
    id: ID! @constraint(type: "primarykey")
    dtTimestamp: Int!
    result: String!
    simSettingsId: ID! @constraint(type: "unique")
}

Next Steps

Now that your data schema is configured and deployed, you're ready to build workflows in the MDK.

User documentation for Optimal Reality