Schema for objects and fields
Create custom objects and fields for your app using Optimizely Data Platform (ODP) and Optimizely Connect Platform (OCP).
Data in Optimizely Data Platform (ODP) is stored in collections called objects (also known as a database table). Objects are composed of fields. Identifiers are a specific type of field that identifity customers. Fields link objects together using relationships.
- Objects – Database tables that act as a collection of client data. Objects contain fields that are the names of the table columns. Objects are connected to other objects by relationships.
- Fields – Columns in a database table (an Object in OCP). All objects have one primary key field that must be a string or number. Fields have one of the following data types:
string
,number
,boolean
,timestamp
.string
– Any printable UTF-8 character, including space. Text is limited to 1024 characters.number
– Represented in standard decimal or integer format (for example:0
,3.14159
,-2.3
,-0.112
).boolean
– Must be0
,1
,true
, orfalse
.timestamp
– Must be ISO 8601 format or UNIX epoch (seconds since January 1, 1970). For example:1435708800
,2015-07-01T00:00:00-00:00
,2015-07-01T12:30:00-07:00
.Note
If time and timezone are not provided, the system assumes 12am UTC for the time.
- Identifiers – Special fields that identify customers. You can only create identifiers for the
customer
object. Learn more about identifiers in the ODP documentation. - Relationships – 1:1 database table relationships.
For more information on viewing your existing default and custom objects and fields in ODP, see Review data fields.
Important
You must prefix all objects and fields that are unique to your app with your
app_id
. For example, if yourapp_id
isacme
, prefix all of your objects and fields withacme
.An exception are fields within an object that your app creates. For example, if your app created an
acme_tickets
object, then you do not have to prefix fields within this object.
There are two ways of creating and updating ODP schema from your app:
- Static – Recommended as it is safer and easier to maintain. With static schema, when users install and upgrade your app, OCP makes sure all objects and fields declared in the app's YAML files are created in the ODP account where the user is installing/upgrading the app.
- Dynamic – Useful when you need to create objects and fields dynamically based on user input.
Important
Change ODP schema with caution. After you create an object or field, you cannot delete or rename it.
For more information about ODP data structure and schema, see the ODP developer documentation.
YAML file properties for defining objects and fields
The following table lists the properties and their descriptions for YAML files that define objects.
Property | Description |
---|---|
name | The name of the object (should be plural). Must be globally unique. You must prefix all custom object names (except the customer object) with your app_id . |
display_name | The user-friendly name used for display within the UI (should be plural). You must prefix all custom object names (except the customer object) with your app name. |
alias | (Optional) The singular name of the object. |
fields.name | The name of the field used for API/SDK calls, CSV uploads, and liquid. Must be unique within the object. |
fields.display_name | The user-friendly name used for display within the UI. Must be unique within the object. |
fields.type | Must be string , number , boolean , or timestamp . |
fields.primary | (Optional) Boolean. Defaults to false .true – The field listed is the primary key for the containing object.false – The field listed is not the primary key for the containing object.At least one primary key is required for new objects. |
relations | (Optional) Should be defined on the parent object. |
relations.name | The name of the relationship used for API/SDK calls and liquid. |
relations.display_name | The user-friendly name used for display within the UI. |
relations.child_object | The child object that is connected to this object. |
relations.join_fields.parent | Any field on this object that you want to relate to another object. |
relations.join_fields.child | Must be a primary key on the child object. |
Create static schema
With static schema, when users install your app, OCP parses all files within src/schema
and creates all described objects and fields. You can either edit the schema of the customer
object, or create new custom objects:
- To add a field or an identifier to the
customer
object, create a file namedcustomers.yaml
within thesrc/schema
folder. - To add a custom object, create a file named
<plural_object_name>.yaml
within thesrc/schema
folder. For example, a file namedacme_tickets.yaml
for theacme_tickets
object.
Note
The file names within the
src/schema
folder must match the name of an existing object or the name of the custom object you want to create.
Below is an example of an src/schema/acme_tickets.yaml
file:
name: acme_tickets
display_name: Acme Tickets
alias: acme_ticket
fields:
- name: acme_ticket_id
display_name: Acme Ticket ID
type: string
primary: true
- name: tag_id
display_name: Tag ID
type: string
relations:
- name: acme_ticket_tag
display_name: Acme Ticket Tag
child_object: acme_ticket_tags
join_fields:
- parent: tag_id
child: acme_ticket_tag_id
Create identifiers
Additionally, for the customers
object, you can create custom identifiers. For example:
name: customers
identifiers:
- name: acme_ios_push_token
display_name: Acme iOS Push Token
merge_confidence: high
messaging: true
Property | Description |
---|---|
identifiers.name | The singular name of the identifier used within API and SDK calls. Must be unique within the object and prefixed by your app_id .All identifiers must include one of the following suffixes: id , hash , number , token , alias , address , key |
identifiers.display_name | The user-friendly name used in the ODP UI to refer to the identifier. Must be unique within the object. |
identifiers.merge_confidence | The confidence level for the identifier. Must be high or low . For more information on identifier confidence levels, see Identifier confidence. |
identifiers.messaging | (Optional) Boolean. Defaults to false .true – You can use this identifier to contact the customer on a channel.false – You can not use this identifier to contact the customer on a channel. |
When you create an identifier, ODP creates three fields:
- The plural version of the identifier (for example,
ios_push_tokens
) on the Customer object that contains a list of 25 last seen identifiers for that customer. - The singular version of the identifier (for example,
ios_push_token
) on the Customer object that contains the last seen identifier for that customer. - An event audit version that is populated when an event comes in with the singular version (for example,
event_ios_push_token
).
All events and data should use the singular version of the identifier name (for example, ios_push_token
).
Create dynamic schema
Use dynamic schema to create customer fields per client. You cannot create these objects and fields in the schema YAML files because they differ for each install.
OCP provides a number of methods to create fields programmatically. For more information, see the Node SDK reference for Fields, Objects, and Relationships.
Usually, dynamically creating objects and fields is performed in lifecycle callback functions. For example, onInstall
or onUpdate
.
Note
When updating schema dynamically, you should always check if the object or field already exists.
Below is an example of dynamically creating an acme_tickets
Object.
import {z} from '@zaiusinc/node-sdk';
await z.schema.createObject({
'name': 'acme_tickets',
'display_name': 'Acme Tickets',
'alias': 'acme_ticket',
'fields': [
{
'name': 'acme_ticket_id',
'display_name': 'Acme Ticket ID',
'type': 'string',
'primary': true
},
{
'name': 'tag_id',
'display_name': 'Tag ID',
'type': 'string'
}
],
'relations': [
{
'name': 'acme_ticket_tag',
'display_name': 'Acme Ticket Tag',
'child_object': 'acme_ticket_tags',
'join_fields': [{
'parent': 'tag_id',
'child': 'acme_ticket_tag_id'
}]
}
]
});
Below is an example of dynamically creating a tag_id
Field.
import {z} from '@zaiusinc/node-sdk';
await z.schema.createField('acme_tickets', {
'name': 'tag_id',
'display_name': 'Tag ID',
'type': 'string'
});
Below is an example of dynamically creating an acme_ticket_tag
Relationship.
import {z} from '@zaiusinc/node-sdk';
await z.schema.createRelation('acme_tickets', {
'name': 'acme_ticket_tag',
'display_name': 'Acme Ticket Tag',
'child_object': 'acme_ticket_tags',
'join_fields': [{
'parent': 'tag_id',
'child': 'acme_ticket_tag_id'
}]
});
Updated about 1 year ago