Clients: Using Master Data
Clients: Using Master Data
Introduction
Now that we are using the data retrieved from the Analytics, we need to save this data and update it. So, every time we retrieve new data we want to update it using Master Data (a database-as-a-service product from VTEX).
Master Data Client
Master Data is the VTEX service that makes it possible to create database architectures for a store. By default, it's used to store and organize customer data, but it's also widely used by VTEX stores to make business rule customizations and create applications for your virtual store. You can configure applications that use the module as a data repository to create a system on top of Master Data, just by modeling new data.
In the current version of Master Data, we use the concept of data entities and use JSON Schema to validate and index documents. One data entity can have many schemas, depending on how you need to use the data stored. You'll need the name of the JSON Schema to implement a query, as will be seen in the following steps.
Note: the JSON Schema is not required for all endpoints. If you don't need to validate your data, you may save your documents without any setup, just indicate the data entity and some access credential. Like your case now, as we need validation, we must create a JSON Schema.
Master Data Documents have unique IDs and can have many customized fields. In the JSON Schema, you can declare fields and indicate the ones that you want to index. Indexed fields can be retrieved in queries.
A Master Data client is already provided in VTEX IO Node Runtime. It is possible to access this client through the Context
, a param which contains all IO Clients in the clients property.
In this step, it will be used to fetch data regarding the top-N most viewed products, where N is a parameter that will be used to get the desired amount of products.
NOTE: It is important to highlight that the Master Data client will be available as long as the correct version of
@vtex/api
is installed in the node folder. It can be used by accessingctx.clients.masterdata
.
Initial setup
This step is optional if you are already using the
appliancetheme
account.
Before following our activity for this step, you will need to set up your Master Data to be able to use it.
So, you'll have to create an entity to save your product list. To do so, using our Master Data API, you'll save a new schema.
- Using Postman or any other API client you prefer, send a
PUT
request to this route:https://{{your-account-name}}.vtexcommercestable.com.br/api/dataentities/course_backend_product_list/schemas/{{your-schema-name}}
with the following headers and body:
Note that you need to fill in some information on the route, such as
your-account-name
andyour-schema-name
. That last one can be anything, but for this tutorial we are going to usev1
(identical to the one used innode/event/updateLiveUsers.ts
).
Headers:
Content-Type: application/json
VtexIdclientAutCookie: {your-token}
Body:
{
"properties": {
"slug": {
"type": "string"
},
"count": {
"type": "number"
}
},
"v-indexed": [
"slug",
"count"
],
"v-security": {
"allowGetAll": true,
"publicRead": [
"slug",
"count"
],
"publicWrite": [
"slug",
"count"
],
"publicFilter": [
"slug",
"count"
]
}
}
To get your VTEX local token for the header, in your terminal run
vtex local token
.
Your request should look like this if you are using Postman:
By doing this, you are not only creating an entity but also creating a new schema to be used during this step.
Now you are good to go!
Using the Master Data client to store information
-
First, we need to setup the policies in our app, to authorize it to use Master Data. To do so, complement the
manifest.json
file://manifest.json { ... }, "credentialType": "absolute", "policies": [ + { + "name": "ADMIN_DS" + }, + { + "name": "outbound-access", + "attrs": { + "host": "api.vtex.com", + "path": "/dataentities/*" + } + } ], "dependencies": { ... }
By doing this, we are guaranteeing that this app has the authorization to access Master Data.
-
Now, to save this data in the Master Data, we need to, first, check for each productSlug, if it is already saved. To do so, we will use a method of the Master Data client called
searchDocuments
. To use it, in thenode/event/updateLiveUsers.ts
file, do something like this://node/event/updateLiveUsers.ts ... + import { COURSE_ENTITY } from '../utils/constants' export async function updateLiveUsers(ctx: EventContext<Clients>) { const liveUsersProducts = await ctx.clients.analytics.getLiveUsers() console.log('LIVE USERS ', liveUsersProducts) + await Promise.all( + liveUsersProducts.map(async ({ slug, liveUsers }) => { + const [savedProduct] = await ctx.clients.masterdata.searchDocuments<{ + id: string + count: number + slug: string + }>({ + dataEntity: COURSE_ENTITY, + fields: ['count', 'id', 'slug'], + pagination: { + page: 1, + pageSize: 1, + }, + schema: 'v1', + where: `slug=${slug}`, + }) + console.log('SAVED PRODUCT', savedProduct) + }) + ) return true }
Note that we are using the
COURSE_ENTITY
, from the global constants, to access your data. -
Now, to make sure we are handling errors, implement a
try-catch
structure. To do so, do something like this:export async function updateLiveUsers(ctx: EventContext<Clients>) { const liveUsersProducts = await ctx.clients.analytics.getLiveUsers() console.log('MOCKED LIVE USERS ', liveUsersProducts) await Promise.all( liveUsersProducts.map(async ({ slug, liveUsers }) => { + try { ... + } catch (e) { + console.log(`failed to update product ${slug}`) + console.log(e) + } }) ) return true }
-
If our product is already saved, we need to update it by incrementing its count. Master Data has a method that allows us to update an existing document or create a new document, if the document does not exist -
createOrUpdateEntireDocument
. To use this method and implement the incrementation on the Master Data entity, in the same file that was changed before, right after the log line of saved product, add this code://node/event/updateLiveUsers.ts export async function updateLiveUsers(ctx: EventContext<Clients>) { await Promise.all( liveUsersProducts.map(async ({ slug, liveUsers }) => { try { ... console.log({savedProduct}) + await ctx.clients.masterdata.createOrUpdateEntireDocument({ + dataEntity: COURSE_ENTITY, + fields: { + count: liveUsers, + slug, + }, + id: savedProduct?.id, + schema: 'v1' + }) } catch { console.log(`failed to update product ${slug}`) console.log(e) } }) ) return true }
Note: if an error is thrown inside an event handler, VTEX IO will retry sending this event.
-
Finally, run
vtex link
and wait for an event to be fired. Once it does, check your terminal for the logs in the code. Break thevtex link
by typingctrl + C
and use the following cURL on the terminal to check the updates on Master Data:curl --location --request GET 'https://api.vtex.com/api/dataentities/course_backend_product_list/search?_fields=slug,count&_schema=v1&an=appliancetheme' \ --header 'Content-Type: application/json'
Attention: If you have a version of Windows earlier than Windows 10, version 1803, it’s necessary to download and install cURL. Otherwise, it is installed by default.
To run the command
cURL
on Windows, it's necessary to substitute single quotes ('
) for double quotes ("
).The result should be like this:
Any questions?
See the answersheet for this step or check our [office hours] on the VTEX Developers channel(https://www.youtube.com/c/VTEXDevelopers)
Help us make this content better!
VTEX IO courses are open source. If you see something wrong, you can open a pull request!
Make a contributionUpdated 9 months ago