Neurelo Schema Language (NSL)
Introduction
The Neurelo Schema Language (NSL) is used to define entities, attributes, relationships, and constraints of a system. The language is based on the json-schema spec, with added capabilities to accurately describe the relationships and constraints within the schema.
Concepts
Object - An object represents an entity in your data source. Each object consists of a name, a collection of properties, and constraints. Each object maps to a table (e.g. in PostgreSQL or MySQL) or a collection (e.g. in MongoDB) in your data source.
Properties - A property represents the fields of an object in your data source e.g. a column in a table (e.g. PostgreSQL or MySQL) or a key in a key:value pair (e.g. in MongoDB). The property definition indicates how a value should be formed and validated, how it maps to the data source object (table or collection) and, optionally, if it represents a relationship to another object.
Enum - An enum is a list of named values that can be used to limit the values that can be assigned to a property.
Constraints - A constraint represents additional definitions or rules that should be applied to an object, like a multi-property index.
Functions - A function can be used when assigning default values to an object’s property e.g. instead of having a hard-coded value, you can rely on your data source capabilities to generate a value for each record.
Relationships - A relationship defines how objects interact between them. They are defined on a per-property basis and specify information such as the cardinality of the relation.
Inner Object - An inner object is used to define a custom property schema, and can be reused across multiple objects, or even to define properties of other inner objects. Inner objects are not mapped to a table or collection. Currently they are only supported when using MongoDB (embedded documents).
Top Level
The top level of a Neurelo Schema has the following format:
objects
must be specified in the top level, however, features
, enums
and innerObjects
are optional.
Objects
Each object is represented by a name and a set of properties:
Optionally, it can include a “sourceName” attribute, that indicates how an object is named in the data source:
And also an optional attribute “constraints” to indicate any extra indexes this entity may have in the data source:
The above example would create an index using multiple properties - id
and name
.
Enums
Each enum is represented by a name and a list of string values. Enums can be used to constrain the possible values for a property in a reusable way:
Properties
Properties define the values contained in an object e.g. in a column in a table (e.g. PostgreSQL or MySQL) or a key in a key:value pair (e.g. in MongoDB). Each property is defined by multiple attributes. These attributes define how the values for the property should be formed and how they map to the underlying data source.
Most of the properties accept the following attributes:
description
- optional, string value to add any documentation about the property. Does not have an actual effect on how the property behaves. For example,default
- optional, object value that defines either a hardcoded value or a function that generates a default value for the property. For example,sourceType
- optional, string or array value to specify the underlying data source type for this property. For examples onsourceType
, refer to the respective property’s documentation.sourceName
- optional, string value to specify how this property is named in the underlying data source. This is particularly useful in MongoDB where[_id
field describes a uniqueobjectId
](https://www.mongodb.com/docs/v2.4/reference/object-id/), which is the primary key for every document. For example,nullable
- optional, boolean value to specify if the property is nullable or not. By default, nullable is set as false which means it’s a required property. Here is example for setting nullable to true -identifier
- optional, boolean value to specify if the property should be treated as a primary key in the underlying data source. For example,unique
- optional, boolean value to specify if the property should be treated as a unique key in the underlying data source. For example,
Boolean
Required attributes: type
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
default
default
Default value can be one of:
Default
true
/false
value. For instance,"default": { "value": true }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
boolean | Boolean | "sourceType": "Boolean" |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
BIT(1) | Bit | "sourceType": "Bit" | |
TINYINT(1) | TinyInt | "sourceType": "TinyInt" |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
bool | Bool | "sourceType": "Bool" |
String
Required attributes: type
Optional attributes: format
, default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
default
default
String supports a wide range of defaults:
Default string value. For instance,
"default": { "value": "SomeValue" }
.dbgenerated
,auto
,cuid
, anduuid
functions. Refer to Function section for further details on these.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
text | Text | "sourceType": "Text" | Default |
varbit | VarBit | "sourceType": "VarBit" | |
uuid | Uuid | "sourceType": "Uuid" | |
xml | Xml | "sourceType": "Xml" | |
inet | Inet | "sourceType": "Inet" | |
citext | Citext | "sourceType": "Citext" | |
point | Point | "sourceType": "Point" | |
bit(n) | Bit | "sourceType": "Bit" | |
"sourceType": ["Bit", 5] | String form defaults length to 1. Array form is used to specify specific length. | ||
char(n) | Char | "sourceType": "Char" | |
"sourceType": ["Char", 5] | String form defaults length to 1. Array form is used to specify specific length. | ||
varchar(n) | VarChar | "sourceType": "VarChar" | |
"sourceType": ["VarChar", 5] | String form allows any length. Array form is used to specify max length. |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
TEXT | Text | "sourceType": "Text" | |
TINYTEXT | TinyText | "sourceType": "TinyText" | |
MEDIUMTEXT | MediumText | "sourceType": "MediumText" | |
LONGTEXT | LongText | "sourceType": "LongText" | |
CHAR(n) | Char | "sourceType": "Char" | |
"sourceType": ["Char", 5] | String form defaults length to 1. Array form is used to specify specific length. | ||
VARCHAR(n) | VarChar | "sourceType": "VarChar" | |
"sourceType": ["VarChar", 5] | Default. String form defaults to max length 80. Array form is used to specify max length. |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
String | String | "sourceType": "String" | Default |
ObjectId | ObjectId | "sourceType": "ObjectId" | Required for BSON id fields. |
Integer
Required attributes: type
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
default
default
Default value can be one of:
Default integer value. For instance,
"default": { "value": 0 }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
integer | Integer | "sourceType": "Integer" | Default |
smallint | SmallInt | "sourceType": "SmallInt" | |
oid | Oid | "sourceType": "Oid" |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
TINYINT | TinyInt | "sourceType": "Boolean" | |
TINYINT UNSIGNED | UnsignedTinyInt | "sourceType": "UnsignedTinyInt" | |
SMALLINT | SmallInt | "sourceType": "SmallInt" | |
SMALLINT UNSIGNED | UnsignedSmallInt | "sourceType": "UnsignedSmallInt" | |
MEDIUMINT | MediumInt | "sourceType": "MediumInt" | |
MEDIUMINT UNSIGNED | UnsignedMediumInt | "sourceType": "UnsignedMediumInt" | |
INT | Int | "sourceType": "Boolean" | Default |
INT UNSIGNED | UnsignedInt | "sourceType": "UnsignedInt" | |
YEAR | Year | "sourceType": "Year" |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
int | Int | "sourceType": "Int" | Default. 32-bit integer |
long | Long | "sourceType": "Long" | 64-bit integer |
Big Int
Required attributes: type
, format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
By default, Big Int maps to bigint
in PostgreSQL, BIGINT
in MySQL, and long
in MongoDB. See sourceType
sub-section for further details.
As big int is a special kind of string, to specify the usage of big int, "format": "bigInt"
is required.
default
default
Default value can be one of:
Default big int value. For instance,
"default": { "value": 0 }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
bigint | BigInt | "sourceType": "BigInt" | Default |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
BIGINT | BigInt | "sourceType": "BigInt" | Default |
BIGINT UNSIGNED | UnsignedBigInt | "sourceType": "UnsignedBigInt" |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
long | BigInt | "sourceType": "BigInt" | Default |
Float
Required attributes: type
, format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
As float is a special kind of number, to specify the usage of float, "format": "float"
is required.
default
default
Default value can be one of:
Default number value. For instance,
"default": { "value": 0.0 }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
double precision | DoublePrecision | "sourceType": "DoublePrecision" | Default |
real | Real | "sourceType": "Real" |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
FLOAT | Float | "sourceType": "Float" | |
DOUBLE | Double | "sourceType": "Double" | Default |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
double | Double | "sourceType": "Double" | Default |
Decimal
Required attributes: type
, format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
As decimal is a special kind of string, to specify the usage of decimal, "format": "decimal"
is required with "type": "string"
.
default
default
Default value can be one of:
Default decimal value. NSL matches decimal values with an optional minus sign, allowing for both integer and decimal parts. For instance, some strings that would match are:
123
,-45
,0.314
,.56
,-123.456
. A default value can be specified as"default": { "value": 0 }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
money | Money | "sourceType": "Money" | |
decimal(p, s) | Decimal | "sourceType": "Decimal" | |
"sourceType": ["Decimal", 3, 1] | Default. String form allows for unconstrained precision. Array form is used to specify the precision and scale. |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
DECIMAL(p, s) | Decimal | "sourceType": "Decimal" | |
"sourceType": ["Decimal", 3, 1] | Default. String form allows for unconstrained precision. Array form is used to specify the precision and scale. |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
decimal | Decimal128 | "sourceType": "Decimal128" | Default |
Date Time
Required attributes: type
and format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
For date time, the format supported is date-time
. This is derived from RFC 3339, section 5.6, in accordance with the JSON schema standard.
date: 4 digit full year “-” 2 digit month “-” 2 digit day
For example, 9th January 2023 is represented as
2023-01-09
time: partial-time time-offset
partial-time
- hour ":" minute ":" secondtime-offset
:"Z" / time-numoffset
, wheretime-numoffset
is ("+" / "-") hour-offset ":" minute-offset.For example, 4:30 pm with a time offset of 15 minutes is represented as
16:30:00+00:15
date-time
: date "T" timeFor example, 12:30 pm on 4th July 1990 can be represented as
1990-07-04T12:30:00Z
. Here, theZ
suffix denotes a UTC offset of 00:00.
Note that the letters T
and Z
used in the date/time syntax must always be upper case.
Our APIs currently only accept complete timestamps. This means you must follow the date-time
format (yyyy-mm-ddTHH:MM:SSZ
) specified above, even if your underlying data source type is just a date
or time
type.
default
default
Date Time supports a wide range of defaults:
Default date-time value. For instance,
"default": { "value": "2024-01-01T12:00:00Z", "format": "date-time" }
.now
anddbgenerated
functions. Refer to Function section for further details on these.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
date | Date | "sourceType": "Date" | |
timestamp(n) | Timestamp | "sourceType": "Timestamp" | |
"sourceType": ["Timestamp", 3] | Default. String form defaults to max 6 digits of precision. Array form is used to specify precision. | ||
timestamptz(n) | Timestamptz | "sourceType": "Timestamptz" | |
"sourceType": ["Timestamptz", 3] | String form defaults to max 6 digits of precision. Array form is used to specify precision. | ||
time(n) | Time | "sourceType": "Time" | |
"sourceType": ["Time", 3] | String form defaults to max 6 digits of precision. Array form is used to specify precision. | ||
timetz(n) | Timetz | "sourceType": "Timetz" | |
"sourceType": ["Timetz", 3] | String form defaults to max 6 digits of precision. Array form is used to specify precision. |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
date | Date | "sourceType": "Date" | |
DATETIME(n) | DateTime | "sourceType": "DateTime" | |
"sourceType": ["DateTime", 3] | Default. String form defaults to max 6 digits of precision. Array form is used to specify precision. | ||
TIME(n) | Time | "sourceType": "Time" | |
"sourceType": ["Time", 3] | String form defaults to max 6 digits of precision. Array form is used to specify precision. | ||
TIMESTAMP(n) | Timestamp | "sourceType": "Timestamp" | |
"sourceType": ["Timestamp", 3] | String form defaults to max 6 digits of precision. Array form is used to specify precision. |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
date | Date | "sourceType": "Date" | |
timestamp | Timestamp | "sourceType": "Timestamp" | Default |
Bytes
Required attributes: type
and format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
As bytes is a special kind of string, to specify the usage of bytes, "format": "bytes"
is required.
default
default
Default value can be one of:
Default byte value. For instance,
"default": { "value": "V2VsY29tZSB0byBOZXVyZWxv" }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
bytea | ByteA | "sourceType": "ByteA" | Default |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
BIT(1) | Bit | "sourceType": "Bit" | |
BINARY | Binary | "sourceType": "Binary" | |
VARBINARY | VarBinary | "sourceType": "VarBinary" | |
TINYBLOB | TinyBlob | "sourceType": "TinyBlob" | |
MEDIUMBLOB | MediumBlob | "sourceType": "MediumBlob" | |
BLOB | Blob | "sourceType": "Blob" | |
LONGBLOB | LongBlob | "sourceType": "LongBlob" | Default |
MongoDB
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
binData | BinData | "sourceType": "BinData" | Default |
JSON
Required attributes: type
and format
Optional attributes: default
, sourceType
, description
, nullable
, sourceName
, identifier
, unique
As a JSON type can itself support a number of basic types, its type
is represented as ["array", "boolean", "integer", "number", "object", "string"]
. Furthermore, format
is required to be of type json
.
default
default
Default value can be one of:
Default JSON value. For instance,
"default": { "value": ["apple gardens", "strawberry fields", "vineyards"] }
.dbgenerated
function. Refer to Function section for further details on this.
sourceType
sourceType
PostgreSQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
json | Json | "sourceType": "Json" | |
jsonb | JsonB | "sourceType": "JsonB" | Default |
MySQL
Data Source Type | NSL sourceType | Examples | Notes |
---|---|---|---|
JSON | Json | "sourceType": "Json" | Default |
MongoDB
In MongoDB, json
is used indicate the flexible property type and that multiple types are supported for that property
Enum
Properties referencing an enum can be used to constrain its possible values to the ones defined in the enum.
The $ref
property is used to reference a specific part of the schema by assigning it a value containing the path to the referenced part:
The example above is referencing Rating
enum defined in the Enums
section.
Optionally, references to enums can define a default value for the property.
Array
Required attributes: type
and items
Optional attributes: description
and sourceName
An array field can be represented by specifying a "type": "array"
, followed by the shape of the individual items the array will contain:
Note that sourceType
can be specified in the items
if necessary.
Relation
A reference in an object represents a relationship between the two of them. The relation
property is used to indicate relationships between objects in the schema definition.
The relation
property contains the following attributes:
attrKey - string or array of strings with the name of the object properties that contain the references to the foreign object.
foreignAttrKey - string or array of strings with the name of the foreign object properties that should match the ones defined in
attrKey
.name - optional, used to disambiguate when multiple relationships between the same models are present.
sourceName - optional, the name that should be used in the datasource for the foreign key index
onUpdate - optional, side effect to use when a parent model is updated. Defaults to
NoAction.
onDelete - optional, side effect to use when a parent model is deleted. Defaults to
NoAction
.The actions supported by
onUpdate
andonDelete
are:Restrict
: Prevents updation/deletion if any child model’s records exist.NoAction
: Similar toRestrict
however the functionality ofNoAction
depends on the database being used. For instance,PostgreSQL: As mentioned in PostgreSQL docs,
NoAction
behaves similar toRestrict
exceptNoAction
allows the check to be deferred until later in the transaction, whereasRestrict
does not.MySQL: For MySQL,
[NoAction
is equivalent toRestrict
](https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-key-referential-actions).MongoDB: When a parent model’s record is updated/deleted, the child model’s records remain as is.
Cascade
: Updating/deleting records from the parent model automatically triggers updation/deletion of corresponding records referenced in the child model.SetNull
: After updating/deleting record from the parent model, the corresponding records referenced in the child model are set toNull
.SetDefault
: After updating/deleting record from the parent model, the corresponding records referenced in the child model are set to their default values.
One to One
In the following example we have two objects: authors and author_details. The author_details object contains the relationship definition, as it is the one that has the author_id foreign key property. On the other hand, the authors object only contains a property with items referencing the author_details object.
One to Many
In the following example we have two objects: authors and books. The books object contains the relationship definition, as it is the one that has the author_id foreign key property. On the other hand, the authors object only contains an array property with items referencing the books object.
Many to Many - implicit
In the following example we have two objects: books and libraries. A book can be found in many libraries, and each library contains many books. To define this type of relationship, where we are only interested in whether or not the records are related, we can use an implicit many to many definition.
Many to Many - explicit
Same scenario as the implicit version, but this time we need to keep track of additional information in the many to many pivot table, like the amount of books each library has purchased.
Functions
Functions can be used to generate the default value for a property. The supported functions are:
auto - Only available for MongoDB. Generates an ObjectId.
autoincrement - Generates an automatically incremented integer value.
cuid - Generates a string value based on the CUID spec.
uuid - Generates a string value based on the UUID spec.
now - Generates a Date Time value with the current data source timestamp.
dbgenerated - Generates a value by executing the provided “rawDbValue”.
rawDbValue
’s value is a database function. For instance, in PostgreSQL,gen_random_uuid()
returns a random UUID that can be used for primary key values.
Functions can be used as follows:
Constraints
Identifier
An identifier constraint can be used to define a multi-property primary key index for an object:
The optional “alias” property will be used in Neurelo’s APIs to allow filtering by all the properties of this constraint.
The optional “sourceName” property indicates how this index constraint is named in the data source.
Unique
A unique constraint can be used to define a multi-property unique index for an object:
The optional “alias” property will be used in Neurelo’s APIs to allow filtering by all the properties of this constraint.
The optional “sourceName” property indicates how this index constraint is named in the data source.
NOTE: The “sort” property is not supported within a unique constraint.
Index
An index constraint can be used to define a single or multi-property index for an object:
The optional “alias” property will be used in Neurelo’s APIs to allow filtering by all the properties of this constraint.
The optional “sourceName” property indicates how this index constraint is named in the data source.
The optional “sort” property indicates the order in which the entries of this index will be stored in the data source.
The optional “length” property indicates the maximum length of the value to be indexed. Only available for MySQL.
The optional “kind” property indicates the type of index to be used in the data source. Defaults to “BTree”. Available options are: Hash, Gist, SpGist, Gin, Brin. Only available for PostgreSQL.
Inner Objects
Only available for MongoDB. Inner Objects are defined in an almost identical way as objects, with the difference that the cannot have identifier or unique properties, nor constraints.
Inner objects can be used to describe complex schemas that can be reused across multiple objects properties via references. These properties will be represented in the underlying database as embedded documents.
Features
Features are extensions to the schema.
User Auth
For a guide on using this feature, seeUser Auth. To enable the feature you just have to specify the version (currently "1"
)
Last updated