Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
Clientes: Usando o Master Data
View in English
This content was migrated from the VTEX Learning Center and is no longer being actively maintained. For the most accurate and up-to-date information, please check the official documentation.

Introdução

Agora que estamos utilizando os dados que são consultados através do cliente de analytics, precisamos salvar esses dados e atualizá-los. Dessa forma, toda vez que os dados são consultados, queremos atualizá-los utilizando o Master Data (uma base de dados como serviço da VTEX).

Cliente do Master Data

Master Data é o serviço da VTEX que torna possível criar arquiteturas de base de dados para uma loja. Em geral, é utilizada para armazenar e organizar dados de clientes, mas também é amplamente utilizada por lojas VTEX para customizações de regras de negócio e para criar aplicações para sua loja virtual. Você pode configurar aplicações que utilizam este módulo como um repositório de dados para criar um sistema em cima do Master Data, sendo necessário apenas a modelagem dos novos dados.

Na versão atual do Master Data, utilizamos o conceito de data entities e, para isso, usa-se o JSON Schema para validar e indexar documentos. Uma entidade de dados pode ter diversos schemas, dependendo de como você utiliza os dados armazenados. Você precisará do nome do JSON Schema para implementar a query, como você verá neste passo.

Nota: o JSON Schema não é necessário para todos os endpoints. Se você não precisa validar seus dados, você pode salvar seus documentos sem nenhum tipo de configuração, apenas indicando a entidade dos dados e provendo credenciais de acesso. No caso deste passo, como precisaremos de validação, é necessário criar um JSON Schema.

Documentos do Master Data tem identificadores únicos e podem ter vários campos customizados. No JSON Schema, você pode declarar os campos e indicar aqueles que você deseja utilizar para indexação. Campos indexados podem ser utilizados como filtros para queries.

Um cliente do Master Data já está disponível para ser utilizado, através do VTEX IO Node Runtime. É possível acessá-lo através do Context, um parâmetro que contém todos os clientes do IO, na propriedade clients.

Neste passo, este cliente será utilizado para pegar informações dos N produtos mais vistos, onde N é um parâmetro que será utilizado para consultar a quantidade desejada de produtos.

Nota: É importante ressaltar que o cliente do Master Data estará disponível para ser utilizado desde que a versão correta do @vtex/api esteja instalada na pasta node. Ele poderá ser acessado através de ctx.clients.masterdata.

Vamos começar?

Configuração inicial

Esse passo é opcional se você já estiver usando a conta appliancetheme.

Antes de começar a atividade desse passo, você precisa configurar o seu Master Data para poder usar do jeito que a atividade propõe.

Então, você precisa criar uma entidade para salvar a sua lista de produtos. Para fazer isso, usando a nossa API do Master Data, você vai salvar um novo schema.

  1. Usando o Postman ou qualquer outro cliente para APIs que preferir, faça um request PUT para esta rota https://{{nome-da-sua-conta}}.vtexcommercestable.com.br/api/dataentities/course_backend_product_list/schemas/{{nome-do-seu-schema}} com os seguintes headers e body:

Note que você precisa preencher algumas informações na rota, como o nome-da-sua-conta e nome-do-seu-schema. Esse último pode ser qualquer nome, mas recomendamos algo como v0.

Headers:


_10
Content-Type: application/json
_10
VtexIdclientAutCookie: {seu-token}

Body:


_29
{
_29
"properties": {
_29
"slug": {
_29
"type": "string"
_29
},
_29
"count": {
_29
"type": "number"
_29
}
_29
},
_29
"v-indexed": [
_29
"slug",
_29
"count"
_29
],
_29
"v-security": {
_29
"allowGetAll": true,
_29
"publicRead": [
_29
"slug",
_29
"count"
_29
],
_29
"publicWrite": [
_29
"slug",
_29
"count"
_29
],
_29
"publicFilter": [
_29
"slug",
_29
"count"
_29
]
_29
}
_29
}

Para pegar um VTEX local token para o header, basta rodar no seu terminal vtex local token.

Seu request deve ser algo parecido com as imagens abaixo se você estiver usando o Postman:

{"base64":"  ","img":{"width":2862,"height":1166,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":188936,"url":"https://user-images.githubusercontent.com/43679629/108750696-182df380-7520-11eb-8cc3-178158ad8e94.png"}}
{"base64":"  ","img":{"width":2868,"height":1676,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":286254,"url":"https://user-images.githubusercontent.com/43679629/108750714-1ebc6b00-7520-11eb-9f61-4a21160bceef.png"}}

Fazendo isso, você não só está criando a entidade mas também criando um novo schema que será usado nessa atividade.

Agora você está pronto para começar!

Utilizando o cliente do Master Data para armazenar informação

  1. Em primeiro lugar, precisamos definir as policies da aplicação, para autorizar o uso do Master Data. Para fazer isso, altere o arquivo manifest.json, como feito abaixo:


    _20
    //manifest.json
    _20
    {
    _20
    ...
    _20
    },
    _20
    "credentialType": "absolute",
    _20
    "policies": [
    _20
    + {
    _20
    + "name": "ADMIN_DS"
    _20
    + },
    _20
    + {
    _20
    + "name": "outbound-access",
    _20
    + "attrs": {
    _20
    + "host": "api.vtex.com",
    _20
    + "path": "/dataentities/*"
    _20
    + }
    _20
    + }
    _20
    ],
    _20
    "dependencies": {
    _20
    ...
    _20
    }

    Fazendo isso, estamos garantindo que esta app tem autorização para acessar o Master Data.

  2. Agora, para salvar os dados no Master Data, precisamos, em primeiro lugar, checar cada productSlug e ver se já está salvo. Para fazer isso, será utilizado um método do cliente do Master Data chamado searchDocuments. Para utilizá-lo, vá ao arquivo node/event/updateLiveUsers.ts, e faça alterações como as mostradas abaixo:


    _28
    //node/event/updateLiveUsers.ts
    _28
    ...
    _28
    + import { COURSE_ENTITY } from '../utils/constants'
    _28
    _28
    export async function updateLiveUsers(ctx: EventContext<Clients>) {
    _28
    const liveUsersProducts = await ctx.clients.analytics.getLiveUsers()
    _28
    console.log('LIVE USERS ', liveUsersProducts)
    _28
    + await Promise.all(
    _28
    + liveUsersProducts.map(async ({ slug, liveUsers }) => {
    _28
    + const [savedProduct] = await ctx.clients.masterdata.searchDocuments<{
    _28
    + id: string
    _28
    + count: number
    _28
    + slug: string
    _28
    + }>({
    _28
    + dataEntity: COURSE_ENTITY,
    _28
    + fields: ['count', 'id', 'slug'],
    _28
    + pagination: {
    _28
    + page: 1,
    _28
    + pageSize: 1,
    _28
    + },
    _28
    + schema: 'v1',
    _28
    + where: `slug=${slug}`,
    _28
    + })
    _28
    + console.log('SAVED PRODUCT', savedProduct)
    _28
    + })
    _28
    + )
    _28
    return true
    _28
    }

    Note que estamos utilizando COURSE_ENTITY, das constantes declaradas globalmente, para acessar os dados da entidade desejada.

  3. Agora, para nos certificarmos de que estamos lidando corretamente com erros, implemente uma estrutura de try-catch. Veja o exemplo abaixo:


    _15
    export async function updateLiveUsers(ctx: EventContext<Clients>) {
    _15
    const liveUsersProducts = await ctx.clients.analytics.getLiveUsers()
    _15
    console.log('MOCKED LIVE USERS ', liveUsersProducts)
    _15
    await Promise.all(
    _15
    liveUsersProducts.map(async ({ slug, liveUsers }) => {
    _15
    + try {
    _15
    ...
    _15
    + } catch (e) {
    _15
    + console.log(`failed to update product ${slug}`)
    _15
    + console.log(e)
    _15
    + }
    _15
    })
    _15
    )
    _15
    return true
    _15
    }

  1. Se o produto já está salvo, precisamos atualizá-lo, de forma a incrementar seu contador de visualizações. O cliente de Master Data tem um método que permite que atualizemos um documento que já existe ou que criemos um novo, no caso do documento não existir - createOrUpdateEntireDocument.

    Para utilizar este método e implementar o incremento na entidade do Master Data, no mesmo arquivo que foi alterado anteriormente, logo após a linha de log, adicione o seguinte bloco de código:


    _24
    //node/event/updateLiveUsers.ts
    _24
    export async function updateLiveUsers(ctx: EventContext<Clients>) {
    _24
    await Promise.all(
    _24
    liveUsersProducts.map(async ({ slug, liveUsers }) => {
    _24
    try {
    _24
    ...
    _24
    console.log({savedProduct})
    _24
    + await ctx.clients.masterdata.createOrUpdateEntireDocument({
    _24
    + dataEntity: COURSE_ENTITY,
    _24
    + fields: {
    _24
    + count: liveUsers,
    _24
    + slug,
    _24
    + },
    _24
    + id: savedProduct?.id,
    _24
    + schema: 'v1'
    _24
    + })
    _24
    } catch {
    _24
    console.log(`failed to update product ${slug}`)
    _24
    console.log(e)
    _24
    }
    _24
    })
    _24
    )
    _24
    return true
    _24
    }

    Nota: se um erro é gerado dentro do handler de eventos, o VTEX IO tentará novamente fazer o envio do evento.

  2. Finalmente, rode vtex link e espere que um evento seja disparado. Uma vez que isso acontece, cheque o terminal por logs no código. Quebre o vtex link através de ctrl + C e utilize o seguinte cURL no terminal para checar as atualizações no Master Data:


    _10
    curl --location --request GET 'https://api.vtex.com/api/dataentities/course_backend_product_list/search?_fields=slug,count&_schema=v1&an=appliancetheme' \
    _10
    --header 'Content-Type: application/json'

    Atenção: Se você tem uma versão do Windows anterior ao Windows 10, versão 1803, é necessário baixar e instalar cURL. Caso contrário, ele já é instalado por default.

    Para rodar o comando cURL no Windows, é necessário substituir as aspas simples (') por aspas duplas (").

    O resultado deve ser algo similar a imagem abaixo:

    {"base64":"  ","img":{"width":1428,"height":444,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":324195,"url":"https://user-images.githubusercontent.com/43679629/85172472-8579de00-b247-11ea-9758-f34a66df29c7.png"}}


Answer sheet

See answer sheet for liveUsersUpdate.ts
liveUsersUpdate.ts

_49
// node/event/liveUsersUpdate.ts
_49
import { Clients } from './../clients/index'
_49
import { EventContext } from '@vtex/api'
_49
import { COURSE_ENTITY } from '../utils/constants'
_49
_49
export async function updateLiveUsers(ctx: EventContext<Clients>) {
_49
const liveUsersProducts = await ctx.clients.analytics.getLiveUsers()
_49
console.log('MOCKED LIVE USERS ', liveUsersProducts)
_49
await Promise.all(
_49
liveUsersProducts.map(async ({ slug, liveUsers }) => {
_49
try {
_49
const [savedProduct] = await ctx.clients.masterdata.searchDocuments<{
_49
id: string
_49
count: number
_49
slug: string
_49
}>({
_49
dataEntity: COURSE_ENTITY,
_49
fields: ['count', 'id', 'slug'],
_49
pagination: {
_49
page: 1,
_49
pageSize: 1,
_49
},
_49
schema: 'v1',
_49
where: `slug=${slug}`,
_49
})
_49
_49
console.log('SAVED PRODUCT', savedProduct)
_49
_49
await ctx.clients.masterdata
_49
.createOrUpdateEntireDocument({
_49
dataEntity: COURSE_ENTITY,
_49
fields: {
_49
count: liveUsers,
_49
slug,
_49
},
_49
id: savedProduct?.id,
_49
})
_49
.then((res) => {
_49
console.log(res)
_49
return res
_49
})
_49
} catch (e) {
_49
console.log(`failed to update product ${slug}`)
_49
console.log(e)
_49
}
_49
})
_49
)
_49
return true
_49
}

See answer sheet for manifest.json
manifest.json

_31
{
_31
"name": "backend-course",
_31
"vendor": "vtex",
_31
"version": "0.0.2",
_31
"title": "Backend Course",
_31
"description": "Reference app for the Backend Course",
_31
"builders": {
_31
"docs": "0.x",
_31
"node": "6.x"
_31
},
_31
"scripts": {
_31
"prereleasy": "bash lint.sh"
_31
},
_31
"credentialType": "absolute",
_31
"policies": [
_31
{
_31
"name": "ADMIN_DS"
_31
},
_31
{
_31
"name": "outbound-access",
_31
"attrs": {
_31
"host": "api.vtex.com",
_31
"path": "/dataentities/*"
_31
}
_31
}
_31
],
_31
"dependencies": {
_31
"vtex.events-example": "0.x"
_31
},
_31
"$schema": "https://raw.githubusercontent.com/vtex/node-vtex-api/master/gen/manifest.schema"
_31
}

On this page