Documentation
Feedback
Guides
App Development

App Development
Getting Started
Creating a Master Data CRUD app

Learn how to create a Master Data CRUD apps in VTEX IO.

This guide will teach you how to build a Master Data CRUD (Create, Read, Update, Delete) application within VTEX IO using the masterdata builder. Master Data is a native key-document database that allows you to efficiently store, search, expand, and personalize your data. While it is possible to integrate Master Data into any VTEX IO app by connecting to the Master Data API, this is not the most efficient approach.

To streamline your development experience, we recommend leveraging the masterdata builder to create apps with Master Data v2 features, including data creation, editing, and deletion.

Before you begin

Before diving into coding your app, it's essential to grasp some fundamental concepts:

Step by step

To create a Master Data app, follow these steps:

Step 1 - Defining the data structure

Before diving into coding, take time to plan your data structure. Since you will be setting up a VTEX IO service app with a focus on Master Data's basic elements, ensure you have well-defined data entities and written schemas prepared for each entity your app will interact with.

For each data entity that your app will interact with, plan and prepare its corresponding JSON schema. See an example below:

Schema example

_24
{
_24
"$schema": "http://json-schema.org/schema#",
_24
"title": "my_schema",
_24
"type": "object",
_24
"properties": {
_24
"string_field_example": {
_24
"type": "string"
_24
},
_24
"number_field_example": {
_24
"type": "number"
_24
},
_24
"boolean_field_example": {
_24
"type": "boolean"
_24
}
_24
},
_24
"required": [
_24
"number_field_example",
_24
"string_field_example"
_24
],
_24
"v-default-fields": [
_24
"number_field_example",
_24
"string_field_example"
_24
]
_24
}

Step 2 - Editing the manifest.json file

  1. Use the VTEX IO CLI and run vtex init to copy the service-example boilerplate files to your computer.
  2. Add the masterdata builder to your manifest file.

_10
"builders": {
_10
...
_10
+ "masterdata": "1.x",
_10
}

  1. Add the following policies to your app’s manifest.json file:

_10
[{
_10
"name": "outbound-access",
_10
"attrs": {
_10
"host": "api.vtex.com",
_10
"path": "/api/*"
_10
}
_10
},
_10
{
_10
"name": "ADMIN_DS"
_10
}]

Step 3 - Using the masterdata builder

  1. Create a folder named masterdata at the root of your app. This will be your Master Data configuration folder.
  2. For each data entity your app interacts with, create a dedicated folder inside the masterdata directory.
  3. Within each data entity folder, create a file named schema.json. The folder structure should resemble the following:

_10
masterdata
_10
| --myEntity
_10
| --schema.json

  1. Populate the schema.json file with the JSON schema corresponding to the respective and save your changes. Notice that each data entity must have its own schema.json with a valid JSON schema.
  2. In the terminal, run vtex link to test your code.

Note that your app creates regular Master Data entities accessible via the Master Data v2 endpoints. The naming convention for the entities follows this pattern: {vendor}_{appName}_{entityName}.

Note that each time you install or link a different version of your app, the masterdata builder creates a new schema with the app’s name and version. Hence, since Master Data v2 data entities have a limit of 60 schemas per entity, ensure to delete unused schemas to prevent from running into issues.

Step - 4 - Generating TypeScript typings

Run vtex setup -i at the root of your project. This command will generate all TypeScript typings for your data entity, making them available for import in your app. You can find them in your node/node_modules folder.

Whenever you change a data entity schema, you must regenerate the TypeScript typings. Hence, if you run into issues related to the data entity typings, try regenerating the typings. Also, ensure to run vtex setup -i before releasing your app so that the typings will not be tied to your development workspace.

Step 5 - Using the node builder

  1. In the terminal, change to the node folder of your app.
  2. Run yarn add @vtex/clients to install the clients package.
  3. Open the file node/clients/index.ts and import the following modules:

_10
import { masterDataFor } from '@vtex/clients'
_10
import { myEntity } from 'vendor.appName' // Replace with the names of your data entity, store, and app.

When importing your data entity typings from the app, follow the format {vendor}.{appName}, as specified in your manifest.json. If the app does not recognize the generated typings import, try deleting the node/node_modules folder. Then run yarn to reinstall dependencies and vtex setup to regenerate the typings. Finally, run vtex link to check if everything is functioning correctly.

  1. In the same node/clients/index.ts file, create a new property for the Clients class to create a client for your data entity. This represents the data entity you are working with. See this code example:

_10
public get entity() {
_10
return this.getOrSet('entity', masterDataFor<myEntity>('entity'))
_10
}

Step 6 - Configuring Master Data triggers

To configure Master Data triggers in your app, follow these steps:

  1. Create a folder named triggers inside your masterdata/{dataEntity} folder.
  2. Create a JSON file inside the triggers folder.
  3. Declare your triggers in the JSON file, following the same format described for the v-triggers field when setting up Master Data v2 triggers.

Step 7 - Creating Master Data functions

Now that your app is set up, you can begin coding Master Data functions, such as saving, editing, retrieving, or deleting data. You can then use these functions in your app’s resolvers and middlewares.

Master Data functions are available via global context through ctx.clients.{entityName}.{function}(). Below, you can see more details on each function. These functions are equivalent to those performed by Master Data v2 endpoints.

Get

The get() function returns a document by its ID. You may specify what fields you want to be returned. If you do not, all fields in the document will be returned.

ArgumentRequiredTypeDescription
idYesStringID of the document you wish to retrieve.
fieldsNoArray of stringsList of the names of the fields you wish to be returned. If not sent, all fields are returned.
Example: Getting a complete document of the Book entity.

_10
ctx.client.Book.get(id: 'sdfg3543df5g4h3d5fh47d')

Example: Getting the name and release date of a given book from the Book entity.

_10
ctx.client.Book.get(id: 'sdfg3543df5g4h3d5fh47d’, fields:['name', 'releaseDate'])

Save

The save() function saves a new document to your data entity and returns the generated ID for that new document.

This function’s arguments follow the format you described when setting up JSON schemas in your data structure.

Example: Saving a new document to the Book data entity.

_10
ctx.client.Book.save({
_10
name: 'Dom Quixote',
_10
releaseDate: 1605,
_10
author: 'Miguel de Cervantes'
_10
})

Update

The update() function an existing document by ID.

ArgumentRequiredTypeDescription
idYesStringID of the document you wish to update.
{document-data}YesCorresponding to the types declared in the schemaThis function’s arguments follow the format you described when setting up JSON schemas in your data structure. Required fields apply even for partial updates.
Example: Updating a document’s rating field in the Book entity.

_10
ctx.client.Book.udpate(
_10
id: 'sdfg3543df5g4h3d5fh47d',
_10
{
_10
name 'Dom Quixote',
_10
rating: 4,5
_10
}
_10
)

Save or update

The saveOrUpdate() function updates an existing document by ID or creates a new document if you do not send an ID.

ArgumentRequiredTypeDescription
idNoStringID of the document you wish to update. If you send an ID, the document is updated. Otherwise, a new document is created.
{document-data}YesCorresponding to the types declared in the schemaThis function’s arguments follow the format you described when setting up JSON schemas in your data structure. Required fields apply even for partial updates.
Example: Updating a document’s rating field in the Book entity.

_10
ctx.client.Book.saveOrUpdate(
_10
id: ‘sdfg3543df5g4h3d5fh47d’,
_10
{
_10
name ‘Dom Quixote’,
_10
rating: 4,5
_10
}
_10
)

Example: Saving a new document to the Book data entity.

_10
ctx.client.Book.saveOrUpdate({
_10
name: 'Dom Quixote',
_10
releaseDate: 1605,
_10
author: 'Miguel de Cervantes'
_10
})

Delete

The delete() function deletes a document by ID.

ArgumentRequiredTypeDescription
idYesStringID of the document you wish to delete.
Example: Deleting a document of the Book entity.

_10
ctx.client.Book.delete(id: 'sdfg3543df5g4h3d5fh47d')

Search

The search() function returns an array of documents that satisfy the criteria described in the arguments.

ArgumentRequiredTypeDescription
pageYesIntegerNumber of the page you wish to retrieve.
pageSizeYesIntegerNumber of documents that should be returned in each page.
fieldsNoArray of stringsNames of the fields you wish to be returned. If not sent, all fields are returned.
whereNoStringFiltering condition.
Example: Searching names and release dates of all books by the author Miguel de Cervantes.

_10
ctx.client.Book.search(
_10
pagination: {
_10
page: 1,
_10
pageSize: 10
_10
},
_10
fields: ['name', 'releaseDate'],
_10
where: 'name=Miguel de Cervantes'
_10
)

Contributors
3
Photo of the contributor
Photo of the contributor
Photo of the contributor
+ 3 contributors
Was this helpful?
Yes
No
Suggest edits (Github)
Contributors
3
Photo of the contributor
Photo of the contributor
Photo of the contributor
+ 3 contributors
On this page