Skip to main content

High Code

Introdução​

Caso você opte por uma integração feita 100% via código, você pode seguir o modelo High Code. Nessa opção você pode desenvolver ou solicitar uma integração modificada para a equipe devapi. Caso você decida desenvolver, você pode seguir os seguintes passos:

Dashboard

Caso este seja o seu primeiro acesso à plataforma e ainda não exista nenhuma automação criada, nenhuma opção será exibida na listagem. Nesse caso, você poderá criar sua primeira automação do zero, respeitando o limite de integrações contratado junto ao time comercial.

Lembre-se, sempre que você criar uma automação, será necessário pelo menos 1 conector, caso não tenha visto ainda sobre o assunto, leia a sessão sobre conectores.​


Iniciando uma Nova Integração:​

Dashboard

Ao clicar em Nova Automação, irá abrir um pequeno Pop-up, nele você irá escolher a integração que seguirá para desenvolvimento de fluxos, no meu caso, escolhi a vtex, por fim eu nomeio o nome da minha automação(que será o seu projeto), no meu caso coloquei teste, pois se trata apenas de uma simulação, mas o recomendável é você colocar o nome ideal do seu projeto.

Note que no retângulo marcado em vermelho há 3 opções:

Dashboard

1° Opção: Simbolo do visual studio code tanto visível quanto apagado, e qual a diferença entre eles?

  • O visível é quando você pode fazer alguma alteração no código da sua integração, geralmente você é responsável por ela e também pela manutenção das funcionalidades.

  • simbolo do visual studio code invisível: quando a DevAPI é responsável por toda a manutenção da integração.

2° Opção: Edição da automação, você consegue editar o nome da automação e os conectores agregados a ela.

3° Opção: Apagar por completo a automação, mas lembre-se, se apagar não terá como recuperar.

Fique atento, por mais que delete uma automação, a quantidade de recursos continuará contando a automação que um dia você já usou.

Abrindo uma Integração para desenvolvimento pela Plataforma:​

Se você for o responsável pelo desenvolvimento/melhorias da sua automação, a opção do visual studio code estará liberada para acesso. Clique nela para iniciar.

Para desenvolvimento é importante que você tenha conhecimento de Node.js, Rotas Https, Git, ou sql caso você utilize também em seu projeto.

Dashboard

Irá abrir um pequeno ambiente para desenvolvimento de código. Caso você preferir codificar por um outro editor, ou pela própria maquina local, entre em contato com a equipe para disponibilizarmos o repositório do seu projeto e realizar o git clone.

1° Opção: Tela cheia, rodar a aplicação, salvar e sair.

Todas as modificações que fizer e for importante será necessário salvar, caso você feche sem salvar tudo será perdido​

2° Opção: A branch por padrão irá ser a Main, não podendo alterar, então caso você queira utilizar o modelo Git Workflow(Fluxo de trabalho com o Git), será necessário clonar o repositório e tentar por outro ambiente.

3° Opção: Terá uma lista de arquivos, estes serão os arquivo que você irá utilizar para montar seus fluxos e regra de negócio, desenvolvendo pela plataforma não há a opção de criar pastas e subpastas. Quando escolhemos o conector, as rotas dele estarão visivéis como dependências.

Na 3° opção marcada em vermelha no anexo, note que existe uma pasta chamada Arquivo, dentro desta pasta existe uma subpasta padrão chamada src e um arquivo index.js:

este arquivo index.js será utilizado como um arquivo mãe, que chamará todos os outros arquivos filhos, não mexa neste arquivo por enquanto. Neste momento, vamos criar um novo arquivo que será responsável pela execução de cada um dos meus fluxos.

Irei fazer um exemplo e o meu objetivo é separar os fluxos por responsabilidade, contemplando:

  • Fluxo de pedidos
  • Fluxo de produtos
  • Fluxo de preços

Para o meu exemplo quero utilizar um fluxo de pedidos para automatizar a comunicação entre a VTEX e o SAP Business One, garantindo a sincronização consistente dos dados comerciais e operacionais entre as plataformas, mesmo tratando-se de ambientes distintos.​

Também quero uma integração de Produtos para simular o fluxo de integração de produtos entre o SAP Business One e a plataforma VTEX, automatizando a criação de produtos no e-commerce a partir dos dados originados no SAP.​

Por fim, meu exemplo em modo simulado gostaria de automatizar e validar o fluxo de sincronização de valores entre uma base interna (DB) e a plataforma VTEX, encenando o papel de um sistema de retaguarda/ERP no controle de preços. Essa integração garante que os preços definidos na base interna sejam corretamente criados ou atualizados na VTEX, mantendo a consistência dos dados comerciais entre os sistemas.​

Por padrão da DevAPI o nome dos arquivos deve sempre iniciar com atm, seguindo o modelo abaixo para o meu exemplo:

  • atm-ordersVtexAtSap.js
  • atm-productsSapAtVtex.js
  • atm-pricingSapAtVtex.js

Note que, após a criação de todos esses arquivos, eles já vêm com uma codificação padrão. Não altere essa codificação neste momento; explicarei em detalhes posteriormente o significado de cada uma.

Por agora, apenas salve as alterações clicando em Commit. Caso contrário, qualquer mudança realizada (inclusive a criação de arquivos) será perdida.

Observe também que, ao realizar o commit pela plataforma, todas as alterações estão sendo feitas na branch master. Portanto, caso o projeto evolua futuramente e novas branches sejam criadas, é importante ter atenção a esse detalhe para evitar alterações na branch incorreta.

Dashboard

Importante, quando criar um projeto, todos os arquivos principais dele não devem ser alterados, substituídos ou excluídos.​

Um exemplo prático clonando na minha maquina local:​

Dashboard

Essas são as configurações padrões que já vem no projeto quando clona ele localmente. Bom de inicio você verá essas opções:

environments.json: Será onde ficarão as suas variáveis de ambiente. operations.json: Será onde ficarão todos os seus Jobs(Tempo de execução dos seus fluxos).

Nesse primeiro momento, tudo estará em branco, pois não configuramos nada e estamos criando do zero, volte novamente na plataforma, vamos configurar o tempo de execução do JOB(que será os seus fluxos, exemplo: Fluxo de Pedido, Fluxo de preço e Produto).

É bom que você já esteja familiarizado com essa interface, caso tenha alguma dúvida sobre ela, volte na sessão de Jobs, trecho da documentação que explicará com mais detalhes, você pode rever em: Introdução Jobs.

Dashboard

Após ter salvo todos os jobs e o tempo de execução de cada um pela plataforma, volte ao código do seu projeto e realize um Git Pull, note que agora o arquivo operations.json foi preenchido, o tempo de execução do seu projeto dependerá dos "schedules".

Dashboard

O arquivo environments já estará preenchido e conterá as configurações das variáveis de ambiente.

Você pode adicionar um arquivo .env com as credenciais sensíveis e fazer referência a essas informações no arquivo environments, garantindo maior segurança e organização.


Para organizarmos melhor o nosso projeto, iremos criar uma pasta chamada services. Nela ficarão as chamadas aos conectores e também poderão ser adicionados pequenos trechos de lógica de acordo com a regra de negócio.

Por exemplo:

  • se o SAP não retornar nenhuma informação, o fluxo deverá retornar um erro;
  • se retornar dados válidos, essas informações deverão ser enviadas ao conector da VTEX.

Muita calma nessa hora 😄 vamos organizar tudo passo a passo, com atenção e clareza.

Caso você precise converter dados de um formato ou estrutura para outro, normalmente com o objetivo de torná-los mais adequados e apropriados para diversas finalidades, como análise, armazenamento ou migração, crie uma pasta chamada data-transformation. Para não poluir tanto o seu fluxo, crie uma pasta chamada functions para poder adicionar pequenas funções, exemplo uma função que formate a data, cnpjs, cpfs e assim por diante.

Você pode ir criando pastas para montar a arquitetura do seu projeto, só não altere/personalize/modifique as pastas/arquivos que já vem por padrão na aplicação.

Após ter feito todo o meu projeto, minha pasta src ficou da seguinte forma:

Dashboard

É importante que você não faça alterações em nenhuma pasta, apenas na src e function-app-settings​


Explicações sobre os arquivos ATM​

Você deve imaginar oque cada linha representa, porém, é válido ressaltar que dentro dos parametros Handle, você deve passar as informações de acordo com o objetivo da sua integração

Parâmetros utilizados no module.exports.handler​

ParâmetroDescriçãoTipo de Execução
(_timer, context)Execução de integração baseada em tempoJob / Scheduler
(request, context)Execução via Webhook (HTTP) ou APIHTTP
(message, context)Execução acionada por mensagens em filaQueue
src/atm-productsSapAtVtex.js

const builder = require('@devapi/kubik') // <--- na importação o builder é obrigatório para está se conectando com o conector, ele que pega os tipos de parametros e vai processar no conector

const { basename } = require('path')

const FILE_NAME = basename(__filename)
.toUpperCase()
.replace('.JS', '') //<-- aqui ele vai iniciar a integração de acordo com o arquivo dela

module.exports.handler = async (context, event) => { //<-- nunca mude o nome do handle e nem faça alterações

const devapi = new builder.Kubik() // <-- aqui você vai instanciar o build, pode colocar o nome que você desejar na constante

try {
//Context.log.info serve para notificar você por logs sobre mensagens de erro ou sucesso que ocorrem na integração, analise a sessão de logs para mais detalhes
context.log.info(`Starting integration event ${event?.eventId} YOUR INTEGRATION`)
context.log.info(`Receiver event: \n${JSON.stringify(event)}`)

// TODO: initialize your services here

await builder.start({
devapi,
logType: builder.LOG_TYPE_JOB,
jobFilename: FILE_NAME,
tenantId: process.env.TENANT_ID,
}) // aqui irá iniciar todo o fluxo

// TODO: your beautiful code goes here

await builder.finish({ devapi })
} catch (error) {
context.log.error(`Error in integration event ${event?.eventId}: ${error.message}`)
throw error
} finally {
await builder.finish({ devapi }) // aqui irá encerrar todo o fluxo
context.log.info(`Finish integration event ${event?.eventId} YOUR INTEGRATION`)
}
}

Para apresentar logs na sua aplicação você pode utilizar 3 tipos, sendo eles:​

  • context.info
  • context.warn
  • context.error

Não é necessário passar context.log.tipo, apenas contex.tipo já servem.​


Criando um arquivo ATM​

Meu exemplo similatório do fluxo de Produtos e Peços no final ficou assim:​
src/atm-productsSapAtVtex.js

// AUTOMATION FILE
// This is the file responsible for controlling the flow of your integration
// Do not change handler name
// The module.exports.handler is required to run the automation

const builder = require('@devapi/kubik')
const { basename } = require('path')

const FILE_NAME = basename(__filename)
.toUpperCase()
.replace('.JS', '')

module.exports.handler = async (_timer, context) => {
const devapi = new builder.Kubik()

// TODO: initialize your services here

await builder.start({
devapi,
logType: builder.LOG_TYPE_JOB,
jobFilename: FILE_NAME,
tenantId: process.env.TENANT_ID,
})

// TODO: your beautiful code goes here

try {
await processProducts({ context, sapb1Service, vtexService, context })
} catch (error) {
context.error(error.message)
throw error
}

await builder.finish({ devapi })
}

const processProducts = async ({ context, sapb1Service, vtexService, context }) => {
const productsResponse = await sapb1Service.findProducts()

if (!productsResponse?.ok) {
context.error(productsResponse?.reason)
return
}

const products = productsResponse?.value

if (!products?.length) {
context.warn('Nenhum produto encontrado no SAP para integração')
return
}

for (const product of products) {
try {
const { ItemCode: productCode } = product
await processProduct({
productCode,
sapb1Service,
vtexService,
context
})
} catch (error) {
context.error(
`Erro ao processar produto ${product.ItemCode}: ${error.message}`
)
}
}
}
const processProduct = async ({
productCode,
sapb1Service,
vtexService,
context
}) => {
// 1️⃣ Busca dados completos do produto no SAP
const productResponse = await sapb1Service.findProductByCode(productCode)

if (!productResponse?.ok) {
throw new Error(productResponse.reason)
}

const sapProduct = productResponse.value

// 2️⃣ Verifica se produto já existe na VTEX
const vtexProductResponse = await vtexService.findProductByRefId(productCode)

if (vtexProductResponse?.ok && vtexProductResponse?.value) {
context.info(
`Produto ${productCode} já existe na VTEX, ignorando criação`
)
return
}

// 3️⃣ Transforma dados SAP → VTEX
const productPayload = vtexProductTransformation({
sapProduct,
productCode
})

context.info(
`Criando produto ${productCode} na VTEX: ${JSON.stringify(productPayload)}`
)

// 4️⃣ Cria produto na VTEX
const createResponse = await vtexService.createProduct(productPayload)

if (!createResponse?.ok) {
throw new Error(createResponse.reason)
}

context.info(
`Produto ${productCode} criado com sucesso na VTEX`,
true
)
}

Fluxo de Preço:​

src/atm-pricingSapAtVtex.js

// AUTOMATION FILE
// This is the file responsible for controlling the flow of your integration
// Do not change handler name
// The module.exports.handler is required to run the automation

const builder = require('@devapi/kubik')
const vtexProductTransformation = require('./data-transformation/vtexProductTransformation.dt.js')
const vtexPriceTransformation = require('./data-transformation/vtexPriceTransformation.dt.js')

const { basename } = require('path')

const FILE_NAME = basename(__filename)
.toUpperCase()
.replace('.JS', '')

module.exports.handler = async (_timer, context) => {
const devapi = new builder.Kubik()

// TODO: initialize your services here

await builder.start({
devapi,
logType: builder.LOG_TYPE_JOB,
jobFilename: FILE_NAME,
tenantId: process.env.TENANT_ID,
})

await synchronize({ context, vtexService, sapb1Service, ibgeService })

// TODO: your beautiful code goes here

await builder.finish({ devapi })
}


async function synchronize({ context, }) {
try {
await processProducts(context)
} catch (error) {
await context.error(error.message)
throw error
}
}

const processProducts = async (context) => {
const productsResponse = await dataTableService.findProducts()

if (!productsResponse?.ok) {
await context.error(productsResponse?.reason)
return
}

const products = productsResponse?.value

if (!products?.length) {
await context.warn('Nenhum produto para ser integrado')
return
}
for (const product of products) {
try {
const { rowKey: productCode } = product
await processProduct(productCode, context)
} catch (error) {
await context.error(error.message)
}
}
}

const processProduct = async (productCode, context) => {
const searchCriteria = { produto_cor: productCode }

const productResponse = await dbService.findProducts({
searchCriteria,
limit: 0
})

if (!productResponse?.ok) {
throw new Error(productResponse.reason)
}

const [productData] = productResponse?.value || []

if (!productData) {
throw new Error(`Produto ${productCode} não encontrado no DB`)
}

let { idproduto_vtex: vtexProductId } = productData

if (!vtexProductId) {
const productPayload = vtexProductTransformation({
sapProduct: productData,
productCode
})

context.info(
`Creating product ${productCode} on VTEX... ${JSON.stringify(productPayload)}`
)

const productCreateResponse = await vtexService.createProduct(productPayload)

if (!productCreateResponse?.ok) {
throw new Error(productCreateResponse.reason)
}

vtexProductId = productCreateResponse.value.Id

await updateVtexProductIdAtDB(productCode, vtexProductId)

context.info(`Produto ${productCode} criado com sucesso na VTEX`, true)
}

const sapPriceResponse = await findSapProductPrice({ productCode })

if (!sapPriceResponse?.ok) {
throw new Error(`Preço não encontrado no SAP para ${productCode}`)
}

const pricePayload = vtexPriceTransformation({
sapPrice: sapPriceResponse.value
})

context.info(
`Updating price for ${productCode} on VTEX... ${JSON.stringify(pricePayload)}`
)

const priceResponse = await vtexService.updatePrice(productCode, pricePayload)

if (!priceResponse?.ok) {
throw new Error(priceResponse.reason)
}

context.info(`Preço do produto ${productCode} atualizado com sucesso`, true)
}


Note que eu modifiquei os parametros do meu handler e como fui chamando o context para me exibir logs.​


Criando uma Service​

Para o meu exemplo, criei um tratamento de erro e sucesso para capurar os logs retornados da rota para a minha Service:​

src/services/vtex.service.js

class VtexService {
#userAgent
constructor(devapi) {
this.devapi = devapi
this.#userAgent = 'Ecommerce/v1.0'
this.credentials = {
account: process.env.VTEX_ACCOUNT,
x_vtex_api_appkey: process.env.VTEX_APP_KEY,
x_vtex_api_apptoken: process.env.VTEX_APP_TOKEN,
}
}

#treatmentResponse(data) {
return {
ok: true,
value: data,
}
}

#treatmentError(error) {
return {
ok: false,
reason: error,
}
}

async findFeedOrders(maxlot = 10) {
try {
const response = await this.devapi.CONNECTOR.VTEX.ORDERS.findOrdersFeed({
devapiContext: this.devapi.context,
maxlot,
userAgent: this.#userAgent,
...this.credentials,
})

if (response.status === 200) {
return this.#treatmentResponse(response.data)
}

throw response
} catch (error) {
const errorMessage = (`Error finding orders feed in VTEX: `, error)
return this.#treatmentError(errorMessage)
}
}

async findProductById(productId) {
const response = await this.devapi.CONNECTOR.VTEX.CATALOG.findCatalogPvtProduct({
devapiContext: this.devapi.context,
id: productId,
...this.credentials,
})

if (response?.status === 200 && response?.data?.RefId) {
return response?.data?.RefId
}
throw response
}

async createProduct(product) {
try {
const response = await this.devapi.CONNECTOR.VTEX.CATALOG.createCatalogPvtProduct({
devapiContext: this.devapi.context,
...this.credentials,
data: product,
})
if (response.status !== 200) throw response

return this.#treatmentResponse(response.data)
} catch (error) {
const errorMessage = `Error creating product on VTEX: ${JSON.stringify(error.data || error.response?.data)}`

return this.#treatmentError(errorMessage)
}
}

async startHandlingOrder(orderId) {
try {
const response = await this.devapi.CONNECTOR.VTEX.ORDERS.createOrderStartHandling({
devapiContext: this.devapi.context,
order_id: orderId,
...this.credentials,
})

if (response?.status === 204) {
return this.#treatmentResponse()
}

throw response
} catch (error) {
return this.#treatmentError(
`Error starting to handle order id ${orderId} on VTEX: ${JSON.stringify(error?.data)}`,
)
}
}


async findOrderById(orderId) {
try {
const response = await this.devapi.CONNECTOR.VTEX.ORDERS.findOrder({
devapiContext: this.devapi.context,
id: orderId,
...this.credentials,
})

if (response.status === 200) {
return this.#treatmentResponse(response.data)
}

throw response
} catch (error) {
return this.#treatmentError(`Error finding order by ID ${orderId} on VTEX: ${JSON.stringify(error?.data)}`)
}
}
}

Note que é passado um padrão HTTP em todas as rotas da service, exemplo:

src/services/vtex.service.js
await this.devapi.CONNECTOR.VTEX.ORDERS.findOrder

Padrão HTTP na Service​

Esse padrão garante padronização, legibilidade e facilidade de manutenção em toda a aplicação, tornando as integrações mais organizadas e previsíveis​

A tabela abaixo define o padrão de nomenclatura utilizado nos conectores da aplicação na DevAPI:

Método HTTPPadrão utilizadoDescrição da ação
GETfindBusca ou consulta dados
POSTcreateCria um novo registro
PUTupdateAtualiza um registro inteiro
PATCHupdateAtualiza parcialmente
DELETEdeleteRemove um registro

Sempre que for chamar uma rota através de um conector, utilize o seguinte padrão inicial:

src/services/vtex.service.js
await this.devapi.CONNECTOR // A palavra CONNECTOR deve ser sempre escrita em maiúsculo.

Após isso, siga a estrutura abaixo:

  • 1° Nome do integrador Representa a plataforma externa que será utilizada na aplicação. Exemplo: VTEX.

  • 2° Fluxo ou domínio Indica o contexto da operação (ex.: Orders, Products, Prices). Exemplo: ORDERS.

  • 3° Padrão da ação (verbo) Define o tipo de operação que será executada, seguindo o padrão HTTP da DevAPI.

  • 4° Objeto ou recurso Representa a entidade que está sendo manipulada.


Exportando uma Function​

Para algumas funções não ficarem espalhadas no seu código principal ATM, você pode criar pequenas funções para executar pequenas ações, exemplo:​

src/functions/generate-linkId.js
module.exports = function generateLinkId(name, code) {
return `${name
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')}-${code}`
}


Crindo um Data-Transformation​

Em um resumo breve oque é um Data-Transformation? A transformação de dados é o processo de converter dados de um formato ou estrutura para outro, tornando-os utilizáveis ​​e valiosos para a tomada de decisões.​

Para o meu exemplo, criei um Data-Transformation para converter os tipos de dados que serão utilizados no fluxo de Preços​

Você deve ter prestado atenção que no meu arquivo de Preços eu utilizei uma rota para buscar dados de um banco de dados, esses valores chegaram na minha integração e agora preciso estruturar para montar um objeto válido que será enviado para a Vtex​

src/data-transformation/vtexProductTransformation.dt.js

const generateLinkId = require("../functions/generate-linkId")

function vtexProductTransformation({ sapProduct, productCode }) {
return {
Name: sapProduct.ItemName,
DepartmentId: sapProduct.VtexDepartmentId || 1,
CategoryId: sapProduct.VtexCategoryId,
BrandId: sapProduct.VtexBrandId,
LinkId: generateLinkId(sapProduct.ItemName, productCode),
RefId: productCode,
IsVisible: true,
Description: sapProduct.ItemDescription || sapProduct.ItemName,
DescriptionShort: sapProduct.ItemName,
ReleaseDate: new Date().toISOString(),
IsActive: true,
ShowWithoutStock: false,
IsKit: false
}
}
return vtexProductTransformation


Criando Rotas Chamadas nos Conectores​

Para a explicação não ficar tão longa irei trazer um código reduzido só para mostrar em um pequeno exemplo:​

src/connectors/index.js
const path = require('path')

const { GET, POST, PUT, PATCH, DELETE } = require(path.resolve('node_modules', '@devapi', 'kubik', 'src', 'requests', 'index.js'))

exports.VTEX_PRICE = { ACCOUNTNAME: { findPricingPrices: async ({ devapiContext, skuid, accountname, x_vtex_api_appkey, x_vtex_api_apptoken }) => { return GET({ devapiContext, url: `https://api.vtex.com/${accountname}/pricing/prices/${skuid}`, headers: {'Authorization': `Basic ${Buffer.from(`${x-vtex-api-appkey}:${x-vtex-api-apptoken}`, 'utf8').toString('base64')}`, 'Content-Type': 'application/json','Accept': 'application/vnd.vtex.ds.v10+json'}, params: {}, data: {} }) }, updatePricingPrices: async ({ devapiContext, accountname, skuid, x_vtex_api_appkey, x_vtex_api_apptoken, markup, baseprice, listprice, fixedprices }) => { return PUT({ devapiContext, url: `https://api.vtex.com/${accountname}/pricing/prices/${skuid}`, headers: {'Authorization': `Basic ${Buffer.from(`${x-vtex-api-appkey}:${x-vtex-api-apptoken}`, 'utf8').toString('base64')}`, 'Content-Type': 'application/json','Accept': 'application/vnd.vtex.ds.v10+json'}, params: {}, data: {'markup': markup, 'basePrice': baseprice, 'listPrice': listprice, 'fixedPrices': fixedprices} }) } } }

exports.VTEX = {
CATALOG: {
findCatalogPvtCategory: async ({
devapiContext,
id,
x_vtex_api_apptoken,
x_vtex_api_appkey,
accountname,
enviroment
}) => {
return GET({
devapiContext,
url: `https://${accountname}.${enviroment}.com.br/api/catalog/pvt/category/${id}`,
headers: {
Authorization: `Basic ${Buffer.from(
`${x-vtex-api-apptoken}:${x-vtex-api-appkey}`,
'utf8'
).toString('base64')}`,
'Content-Type': 'application/json',
Accept: 'application/vnd.vtex.ds.v10+json'
},
params: {},
data: {}
})
},

ORDERS:{
findOrdersFeed: async ({ devapiContext, account, x_vtex_api_apptoken, x_vtex_api_appkey, maxlot }) => {
return GET({
devapiContext,
url: `https://${account}.vtexcommercestable.com.br/api/orders/feed`,
headers: {
'X-VTEX-API-AppToken': x_vtex_api_apptoken,
'X-VTEX-API-AppKey': x_vtex_api_appkey,
'Content-Type': 'application/json',
Accept: 'application/vnd.vtex.ds.v10+json',
},
params: {
maxlot: maxlot,
},
})
},
}
}
}

Organização:​

  • 1° Na seção identificada como exports.VTEX = { ... }, você deve definir o nome do conector que será utilizado pelas rotas. É possível trabalhar com mais de um conector no mesmo projeto. As rotas devem ser organizadas de acordo com o domínio que representam — como pedidos, catálogo, preços, entre outros. Não é necessário criar múltiplos arquivos para cada conector: todas as rotas devem ser centralizadas em um único arquivo index.js, sendo agrupadas por categoria para facilitar a organização e a manutenção.

Dashboard

No início da função, é utilizado o padrão HTTP customizado da TESTESK2 como nome da função (find, create, update, delete).​

No return, é utilizado o método HTTP padrão (GET, POST, PUT, PATCH ou DELETE) para efetuar a chamada da rota.​