Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
Eventos: recebendo e lidando com eventos
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

Algumas interações no VTEX IO podem gerar eventos e estes podem ser utilizados como gatilhos para ações, como a atividade presente neste passo. Por enquanto, utilizaremos os eventos disparados pela app events-example.

Eventos no VTEX IO

Em apps do VTEX IO, eventos podem ser disparados e utilizados como gatilhos para ações. Por exemplo, uma app que escuta por pedidos e ativa um gatilho de email de confirmação. É importante ressaltar que eventos são dependentes da conta e do workspace, o que significa que são apenas visíveis pela conta e pelo workspace de onde foram disparados. Ou seja, eventos disparados no seu workspace pessoal de desenvolvimento serão apenas escutados por apps que estão linkadas no mesmo workspace.

Vamos começar?

Ouvindo eventos na aplicação

  1. Em primeiro lugar, vamos começar com o disparo de eventos sendo feito através da app events-example. Esta app irá disparar um evento a cada X segundos. Após rodar o comando vtex link no diretório de events-example, clique na rota de healthcheck disponível e uma mensagem "ok" deve aparecer no navegador:

    {"base64":"  ","img":{"width":1426,"height":386,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":89920,"url":"https://user-images.githubusercontent.com/43679629/83802091-8c69f380-a680-11ea-82af-a438fb73f40b.png"}}

    Este acesso à rota de healthcheck cria um contexto de cache que é necessário para que o VTEX IO dispare eventos. Sem isso, a app events-example não será capaz de disparar eventos que sua app irá ouvir.

  2. Agora, precisamos adicionar o handler de eventos na declaração de Service, que é responsável por definir o que a app vai fazer enquanto estiver ouvindo os eventos que podem chegar. Para fazer isso, no arquivo /node/index.ts, incremente a declaração de Service:


    _24
    //node/index/ts
    _24
    _24
    + const THREE_SECONDS_MS = 3 * 1000
    _24
    + const CONCURRENCY = 10
    _24
    _24
    export default new Service<Clients, State, ParamsContext>({
    _24
    clients: {
    _24
    implementation: Clients,
    _24
    options: {
    _24
    default: {
    _24
    retries: 2,
    _24
    timeout: 10000,
    _24
    },
    _24
    + events: {
    _24
    + exponentialTimeoutCoefficient: 2,
    _24
    + exponentialBackoffCoefficient: 2,
    _24
    + initialBackoffDelay: 50,
    _24
    + retries: 1,
    _24
    + timeout: THREE_SECONDS_MS,
    _24
    + concurrency: CONCURRENCY,
    _24
    + },
    _24
    + },
    _24
    + },
    _24
    })

    Passando por cada uma das configurações, temos o seguinte:

    CampoTipoDescrição
    exponentialTimeoutCoefficientsecondsfator exponencial em que timeout é incrementado a cada tentativa
    exponentialBackoffCoefficientsecondsfator exponencial em que o backoff delay será incrementado a cada tentativa
    initialBackoffDelaysecondstempo que a app irá esperar até a próxima tentativa
    retries-quantidade máxima de tentativas da app
    timeoutsecondstimeout até ser considerado como uma tentativa mal sucedida
    concurrency-quantidade de processos simultâneos que o evento é capaz de ter

    Ao adicionar esse código ao Service, estamos adicionando ao Client de Service a capacidade de lidar com eventos. Neste ponto, não estamos utilizando ainda os clientes em si ao lidar com eventos.

    Por enquanto, vamos apenas criar um log de recebimento de eventos. Para criar este handler, vá ao arquivo liveUsersUpdate.ts, que se encontra na pasta /node/event e faça as seguintes alterações:


    _10
    //node/event/liveUsersUpdate.ts
    _10
    export async function updateLiveUsers() {
    _10
    console.log('EVENT HANDLER: received event')
    _10
    }

  3. Após adicionar o bloco de código mencionado anteriormente, precisamos declarar em Service, a referência para esta função. No arquivo /node/index.ts, adicione o seguinte código:


    _10
    ...
    _10
    + import { updateLiveUsers } from './event/liveUsersUpdate'
    _10
    ...
    _10
    _10
    export default new Service<Clients, State, ParamsContext>({
    _10
    ...
    _10
    + events: {
    _10
    + liveUsersUpdate: updateLiveUsers,
    _10
    + },
    _10
    })

  4. Também é necessário modificar o arquivo service.json. De forma a ouvir os eventos que são enviados, precisamos declarar isto para darmos a app de serviço que estamos desenvolvendo esta capacidade. É possível fazer isso através das seguintes alterações no arquivo service.json:


    _16
    //node/service.json
    _16
    {
    _16
    "memory": 128,
    _16
    "ttl": 10,
    _16
    "timeout": 10,
    _16
    "minReplicas": 2,
    _16
    "maxReplicas": 10,
    _16
    "workers": 4,
    _16
    + "events": {
    _16
    + "liveUsersUpdate": {
    _16
    + "sender": "vtex.events-example",
    _16
    + "keys": ["send-event"]
    _16
    + }
    _16
    },
    _16
    ...
    _16
    }

    Note que fazemos esta declaração ao utilizar o resolver de eventos, definir a referência para a app que efetivamente dispara os eventos (declarada como sender) e, por fim, adicionar a referência à key do evento (declarada como keys).

  5. Por fim, rode o comando vtex link e espere que os eventos sejam disparados através da app events-example. Quando escutados, o log deve aparece no terminal, como na imagem abaixo:

    {"base64":"  ","img":{"width":1442,"height":486,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":134467,"url":"https://user-images.githubusercontent.com/43679629/83823425-5f323b00-a6aa-11ea-816a-68525e5800d7.png"}}


Answer sheet

See answer sheet for index.ts
index.ts

_56
// node/index.ts
_56
import {
_56
LRUCache,
_56
Service,
_56
ServiceContext,
_56
ParamsContext,
_56
RecorderState,
_56
method,
_56
} from '@vtex/api'
_56
import { Clients } from './clients'
_56
import { analytics } from './handler/analytics'
_56
import { updateLiveUsers } from './events/liveUsersUpdate'
_56
_56
// Create a LRU memory cache for the Status client.
_56
// The @vtex/api HttpClient respects Cache-Control headers and uses the provided cache.
_56
const memoryCache = new LRUCache<string, any>({ max: 5000 })
_56
metrics.trackCache('status', memoryCache)
_56
_56
const TREE_SECONDS_MS = 3 * 1000
_56
const CONCURRENCY = 10
_56
_56
declare global {
_56
type Context = ServiceContext<Clients, State>
_56
_56
interface State extends RecorderState {
_56
code: number
_56
}
_56
}
_56
_56
export default new Service<Clients, State, ParamsContext>({
_56
clients: {
_56
implementation: Clients,
_56
options: {
_56
default: {
_56
retries: 2,
_56
timeout: 10000,
_56
},
_56
events: {
_56
exponentialTimeoutCoefficient: 2,
_56
exponentialBackoffCoefficient: 2,
_56
initialBackoffDelay: 50,
_56
retries: 1,
_56
timeout: TREE_SECONDS_MS,
_56
concurrency: CONCURRENCY,
_56
},
_56
},
_56
},
_56
routes: {
_56
analytics: method({
_56
GET: [analytics],
_56
}),
_56
},
_56
events: {
_56
liveUsersUpdate: updateLiveUsers,
_56
},
_56
})

See answer sheet for liveUsersUpdate.ts
liveUsersUpdate.ts

_10
//node/event/liveUsersUpdate.ts
_10
export async function updateLiveUsers() {
_10
console.log('EVENT HANDLER: received event')
_10
}

See answer sheet for service.json
service.json

_21
// node/service.json
_21
{
_21
"memory": 128,
_21
"ttl": 10,
_21
"timeout": 10,
_21
"minReplicas": 2,
_21
"maxReplicas": 10,
_21
"workers": 4,
_21
"events": {
_21
"liveUsersUpdate": {
_21
"sender": "vtex.events-example",
_21
"keys": ["send-event"]
_21
}
_21
},
_21
"routes": {
_21
"analytics": {
_21
"path": "/_v/app/analytics/realTime",
_21
"public": true
_21
}
_21
}
_21
}

On this page