Tailor DB
The primary database within Tailor Platform, where you store and retrieve your data, is known as Tailor DB. Tailor DB provides a flexible and scalable database that you build using schema. A GraphQL endpoint is automatically generated, enabling seamless fetching, creation, updating, and deletion of records. Additionally, it allows for easy sorting and filtering by any field.
Defining a schema
A data model of your application is defined by the schema. Although multiple data models can be defined in one single schema file, we recommend using one or a few data models per one schema file for readability.
The schema can be defined using either CUE or Terraform, with templates available in both configuration languages. Using a single command, the Tailor platform converts your schema into GraphQL SDL (Schema Definition Language) to generate the GraphQL API.
Folder structure overview
Below is the folder structure of Inventory Management System(IMS) app example in the tutorial.
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">applications</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">auth</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">pipeline</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">provider</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">tailordb_product</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">terraform</span><span style="color: var(--shiki-color-text)">.tfvars</span></span>
<span><span style="color: var(--shiki-color-text)">├── </span><span style="color: var(--shiki-token-constant)">variables</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span><span style="color: var(--shiki-color-text)">└── </span><span style="color: var(--shiki-token-constant)">workspaces</span><span style="color: var(--shiki-color-text)">.tf</span></span>
<span></span>
Root Tailor DB schema
The tailordb.tf
file defines a TailorDB resource for creating and organizing GraphQL types (data models).
This resource acts as a container where you'll define your data models.
Here is how tailordb.tf
looks like.
<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"tailor_tailordb"</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"ims"</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">workspace_id</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">tailor_workspace.ims.id</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">namespace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"ims"</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
Main data model schema
In Tailor DB, the GraphQL APIs are automatically generated based on schemas.
Here's how to define a Product
type schema in the IMS application using Terraform.
To create a new data model, use the tailor_tailordb_type
resource with the following configuration:
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"tailor_tailordb_type"</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"product"</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">workspace_id</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">tailor_workspace.ims.id</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">namespace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">tailor_tailordb.ims.namespace</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">name</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"Product"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">description</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"Product data schema"</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">settings</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">draft</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">fields</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">title</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"string"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">description</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"Title of the product"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">index</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">required</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">description</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"string"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">description</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">"Description of the product"</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">type_permission</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">local.permission_everyone</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span></span>
Basic structure of a Schema
The basic schema configuration is composed of three key elements: Type name
, Description
, and Fields
.
In this context, Fields
represent an object that establish the field names for a given model.
In GraphQL terminology, an individual data model is called a Type, which parallels the concept of a Table in relational databases.
Here are the overview of each element.
- Name of the Type (Required) : Name of the type is defined as the root key, in the example above "Task".
Description
(Required) : Description of the Type. This will appear in GraphQL SDL and GraphQL Playground.Fields
(Required) :fields
is an object to define fields within the Type. Schema defines one or more fields. We can define data types, link the resource, add validation, or put constraints to the fields. See Fields for more information.
Permission in a Schema
With TypePermission
field, we can control the access to data.
We can grant read, write, or delete permissions to specific users, roles, or groups.
By default, no one has access to the data.
See Permission for more information.
Additional options in Schema
Settings
Enabling advanced features in Settings
field allows you to generate additional GraphQL queries.
Available features are aggregation of data, bulk upsert, plural form for uncountable nouns and TailorDB CDC.
See Advanced API for more information.
Directives
Directive is a GraphQL concept, that provides a way to add additional instructions to GraphQL queries without having to modify the schema. This allows developers to use GraphQL to access the same data in different ways without having to change the underlying data structure. See Advanced API for more information.
Extends
The Extends
option enables the extension of the types defined in other sub-graphs, like StateFlow.
With this option enabled, CRUD GraphQL queries become available in Tailor DB.
See Advanced API for more information.