Data Schema in Tailor Platform
This tutorial demonstrates how a data schema is mapped to GraphQL APIs.
- Complete Quickstart first If you haven't yet built the Inventory Management System app from our template.
Data 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. See Tailor DB concept page to learn more about schema.
Tutorial steps
- Open GraphQL playground
- View Product type
- See how the configuration is mapped to the GraphQL APIs
1. Open GraphQL Playground
To get started, open the GraphQL playground by navigating to your Tailor Platform endpoint's URL and appending /playground
at the end. For example, if your endpoint URL is https://{APP_NAME}.erp.dev
, the GraphQL playground URL would be https://{APP_NAME}.erp.dev/playground
.
Alternatively you can use our CLI to open the GraphQL playground in your browser.
<span><span style="color: var(--shiki-token-comment)"># Open the browser and open the GraphQL playground</span></span>
<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">app</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">open</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">-n</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">ims</span></span>
<span></span>
2. View Product
type
Open the tailordb_product.tf
file in your application's repository. This file defines the schema for the Product
type. The schema looks like this:
<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 style="color: var(--shiki-token-function)">publish_record_events</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 style="color: var(--shiki-token-function)">shopifyID</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)">"Shopify product ID"</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)">handle</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)">"Product handle"</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)">featuredImageID</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)">"uuid"</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)">"Featured image ID"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">foreign_key</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)">"ProductImage"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">field</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)">"id"</span></span>
<span><span style="color: var(--shiki-color-text)"> }</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)">featuredImage</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)">"ProductImage"</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)">"Featured image of the product"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">source</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)">"featuredImageID"</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)">inStock</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)">"integer"</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)">"Quantity of the product"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">validate</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>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">//</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">inStock</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">value</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">must</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">be</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">less</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">than</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">100</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">or</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">over</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">103</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)">script</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)">"((value, data) => { return value >=100 && value <=103})(_value, _data)"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">action</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)">"deny"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">error_message</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)">"inStock value must be less than 100 or over 103"</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)"> ]</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-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>
3. See how the configuration is mapped to the GraphQL APIs
Now that you've seen the schema definition in the product configuration file, let's explore how this maps to the GraphQL API. In the GraphQL playground, you can test the API with a query like the one below:
<span><span style="color: var(--shiki-token-keyword)">query</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)"> products {</span></span>
<span><span style="color: var(--shiki-color-text)"> edges {</span></span>
<span><span style="color: var(--shiki-color-text)"> node {</span></span>
<span><span style="color: var(--shiki-color-text)"> id</span></span>
<span><span style="color: var(--shiki-color-text)"> title</span></span>
<span><span style="color: var(--shiki-color-text)"> handle</span></span>
<span><span style="color: var(--shiki-color-text)"> description</span></span>
<span><span style="color: var(--shiki-color-text)"> featuredImageID</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)"> }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
This query will return a list of Product
objects with the specified fields. You can see how the schema defined in the config file is used to create the GraphQL API, allowing you to interact with your data easily.
You will notice some of the field like id
is generated without specifically defined in product
config. This is a pre-defined field and the name of the field is reserved. Please refer to Auto-generated fields.
Next steps
In the following tutorials, you'll learn how to modify the schema by adding fields to existing types or creating new types for your application.