Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
GraphQL
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 a contagem dos produtos está atualizada, precisamos consultar os dados dos N produtos mais vistos. Para tal, é possível utilizar o Master Data para consultar os dados de visitas às páginas de produto e ordená-los pelo campo count. Também podemos limitar a quantidade de produtos que são consultados, de forma a criar um rank customizado de produtos mais visitados.

GraphQL

Para pegar os dados de visitas por produto, vamos utilizar GraphQL, a tecnologia utilizada pelo VTEX IO para consulta de dados, para implementar uma query para o Master Data. GraphQL permite que implementemos queries de maneira simples e rápida, especificando os dados que você deseja consultar. Isto faz com que a API seja confiável, dado que o GraphQL controla os dados que são consultados, ao invés do servidor em si.

Também é a única maneira de criar uma interface entre os serviços e as aplicações de frontend.

Portanto, o GraphQL utiliza tipos e um schema para as queries para especificar os dados consultados, e resolvers para pegar apenas os dados necessários.

Vamos lá?

Recuperando dados do Master Data

  1. Dentro do diretório /graphql, crie uma pasta chamada /types. Nesta pasta, crie o arquivo productView.graphql e declare o tipo de lista de produto que você quer consultar:


    _10
    # /graphql/types/productView.graphql
    _10
    type ProductView {
    _10
    slug: String
    _10
    count: Int
    _10
    }

  2. Ainda na pasta /graphql, defina o schema no arquivo schema.graphql:


    _10
    type Query {
    _10
    productList(topN: Int): [ProductView]
    _10
    }

    Tenha em mente que o schema irá definir a estrutura da query e os dados que serão recuperados.

    Além disso, na declaração do schema, você pode incluir diretivas. Em alguns casos, é necessário, como casos em que precisamos pegar tokens de usuário ou usar cookies (exemplo: OrderForm). Para ler um pouco mais sobre isso, veja este link.

  3. Com o schema, os tipos e a query definida, precisamos criar o resolver da query. O resolver é o código a ser executado quando uma query acontece. No nosso caso, queremos executar um scroll no Master Data, ordenando pela contagem (já que queremos pegar os N produtos mais vistos) e limitando o tamanho da página (top N). Para definir este resolver, crie a pasta /node/resolvers e nela, crie o arquivo products.ts e faça o seguinte:


    _17
    // node/resolvers/products.ts
    _17
    import { COURSE_ENTITY } from '../utils/constants'
    _17
    _17
    export const productList = async (
    _17
    _: any,
    _17
    { topN }: { topN: number },
    _17
    { clients: { masterdata } }: Context
    _17
    ) =>
    _17
    masterdata
    _17
    .scrollDocuments({
    _17
    dataEntity: COURSE_ENTITY,
    _17
    fields: ['count', 'slug'],
    _17
    schema: 'v1',
    _17
    size: topN,
    _17
    sort: `count DESC`,
    _17
    })
    _17
    .then(({ data }) => data)

    Nota: você pode checar a documentação a respeito do uso de scroll no Master Data neste link.

  4. Importe o resolver no arquivo index.ts:


    _10
    import { productList } from './resolvers/products'

  5. Por fim, precisamos atualizar o arquivo index.ts para definir o resolver e a query. Complete a declaração de Service como abaixo:


    _10
    },
    _10
    graphql: {
    _10
    resolvers: {
    _10
    Query: {
    _10
    productList,
    _10
    },
    _10
    },
    _10
    },
    _10
    })

    Também é necessário lembrar de adicionar o builder de graphql ao arquivo manifest.json:


    _10
    //manifest.json
    _10
    "builders": {
    _10
    + "graphql": "1.x",
    _10
    "docs": "0.x",
    _10
    "node": "6.x"
    _10
    },

    Finalmente, linke a app e você poderá ver no terminal uma rota GraphQL. O resultado deve ser semelhante ao da imagem abaixo:

    {"base64":"  ","img":{"width":1840,"height":744,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":619127,"url":"https://user-images.githubusercontent.com/43679629/82947940-3c4faa80-9f77-11ea-8bfa-138d11cdec1f.png"}}


Answer sheet

See answer sheet for index.ts
index.ts

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

See answer sheet for manifest.json
manifest.json

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

See answer sheet for product.ts
product.ts

_17
// node/resolvers/product.ts
_17
import { COURSE_ENTITY } from '../utils/constants'
_17
_17
export const productList = async (
_17
_: any,
_17
{ topN }: { topN: number },
_17
{ clients: { masterdata } }: Context
_17
) =>
_17
masterdata
_17
.scrollDocuments({
_17
dataEntity: COURSE_ENTITY,
_17
fields: ['count', 'slug'],
_17
schema: 'v1',
_17
size: topN,
_17
sort: `count DESC`,
_17
})
_17
.then(({ data }) => data)

See answer sheet for productList.graphql
productList.graphql

_10
# graphql/types/productList.graphql
_10
type ProductList {
_10
slug: String
_10
count: Int
_10
}

See answer sheet for schema.graphql
schema.graphql

_10
# graphql/schema.graphql
_10
type Query {
_10
productList(topN: Int): [ProductView]
_10
}

On this page