Documentation
Feedback
Guides
App Development

App Development
ServicesDeveloping services on VTEX IO
6. Using GraphQL to retrieve data from Master Data

Now that we have updated the product count, we need to retrieve the top N most viewed products. To do so, we can use Master Data to retrieve the product page view data and sort by the count field. We can also limit the length of retrieved products, creating a customized size rank of most-visited products.

To achieve this objective, we'll employ GraphQL, the technology used by VTEX IO for data retrieval and interface between services and front-end applications. GraphQL allows implementing queries for fetching the exact data you need via types, schemas, and resolvers.

Using the graphql builder

To enable the use of GraphQL in your VTEX IO app, add the graphql builder to the app's manifest.json file.

service-course-template/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
"graphql": "1.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
}

Creating the GraphQL type

Within the service-course-template/graphql folder, create a folder named types. Inside this folder, create the productView.graphql file to declare the type of the product list we intend to retrieve.

service-course-template/manifest.json
service-course-template/graphql/types/productView.graphql

_10
type ProductView {
_10
slug: String
_10
count: Int
_10
}

Creating the GraphQL schema

Still within the service-course-template/graphql folder, define the schema in the schema.graphql file. This schema outlines the structure of our query and the data to be retrieved.

Optionally, directives can be included for scenarios like obtaining user tokens or utilizing cookies. Check out the graphql-example app for advanced usage examples.

service-course-template/manifest.json
service-course-template/graphql/types/productView.graphql
service-course-template/graphql/types/schema.graphql

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

Creating the GraphQL resolver

With the schema, types, and query defined, create the query's resolver. The resolver determines the actions executed when a query is invoked. In our case, we want to perform a scroll on Master Data, ordering by the count (to obtain the top most viewed products) and limiting the page size (the top N).

Back to our node implementation, define the resolver by creating a node/resolvers folder. In this new folder, add a file named products.ts and populate it with the code presented in the right panel.

service-course-template/manifest.json
service-course-template/graphql/types/productView.graphql
service-course-template/graphql/types/schema.graphql
service-course-template/node/resolvers/products.ts

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

Using the GraphQL resolver

Import the resolver into the node/index.ts file and set up the graphql section, connecting your defined queries with the underlying data retrieval logic (productList).

Note that resolvers act as the glue between your GraphQL schema and the actual data-fetching logic. When a GraphQL query is executed, the resolver associated with each field in the query is invoked to obtain the corresponding data. In this case, when the productList query is executed, the productList resolver function (products.ts) is triggered to fetch the top N most viewed products from Master Data.

service-course-template/manifest.json
service-course-template/graphql/types/productView.graphql
service-course-template/graphql/types/schema.graphql
service-course-template/node/resolvers/products.ts
service-course-template/node/index.ts

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

Linking the app

Finally, run vtex link and access the provided GraphQL route.

service-course-template/manifest.json
service-course-template/graphql/types/productView.graphql
service-course-template/graphql/types/schema.graphql
service-course-template/node/resolvers/products.ts
service-course-template/node/index.ts
Terminal

_10
17:31:10.803 -info: Build accepted for vtex.service-course-template@0.0.1 at myaccount/myworkspace vtex.builder-hub@0.250.0
_10
17:31:10.818 - info: Starting build for app vtex.service-course-template@0.0.1 vtex.builder-hub@0.250.0
_10
17:31:19.588 - warn: node builder overrode the following options in tsconfig.json: target: 'es2017' = 'es2019' vtex.builder-hub@0.250.0
_10
17:31:27.227 - info: Bundle: 26 files - 34.44MB vtex.builder-hub@0.250.0
_10
17:31:27.228 - info: Sent bundle to Apps in 3869ms vtex.builder-hub@0.250.0
_10
17:31:27.229 - info:App linked successfully vtex.builder-hub@0.250.0
_10
17:31:27.230 - info: You can try out the queries in this app using the GraphiQLIDE available at:
_10
https://myworkspace--myaccount.myvtex.com/_v/private/vtex.service-course-template@0.0.1/graphiql/v1 vtex.builder-hub@0.250.0

Using the graphql builder

To enable the use of GraphQL in your VTEX IO app, add the graphql builder to the app's manifest.json file.

Creating the GraphQL type

Within the service-course-template/graphql folder, create a folder named types. Inside this folder, create the productView.graphql file to declare the type of the product list we intend to retrieve.

Creating the GraphQL schema

Still within the service-course-template/graphql folder, define the schema in the schema.graphql file. This schema outlines the structure of our query and the data to be retrieved.

Optionally, directives can be included for scenarios like obtaining user tokens or utilizing cookies. Check out the graphql-example app for advanced usage examples.

Creating the GraphQL resolver

With the schema, types, and query defined, create the query's resolver. The resolver determines the actions executed when a query is invoked. In our case, we want to perform a scroll on Master Data, ordering by the count (to obtain the top most viewed products) and limiting the page size (the top N).

Back to our node implementation, define the resolver by creating a node/resolvers folder. In this new folder, add a file named products.ts and populate it with the code presented in the right panel.

Using the GraphQL resolver

Import the resolver into the node/index.ts file and set up the graphql section, connecting your defined queries with the underlying data retrieval logic (productList).

Note that resolvers act as the glue between your GraphQL schema and the actual data-fetching logic. When a GraphQL query is executed, the resolver associated with each field in the query is invoked to obtain the corresponding data. In this case, when the productList query is executed, the productList resolver function (products.ts) is triggered to fetch the top N most viewed products from Master Data.

Linking the app

Finally, run vtex link and access the provided GraphQL route.

service-course-template/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
"graphql": "1.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
}

Contributors
1
Photo of the contributor
+ 1 contributors
Was this helpful?
Yes
No
Suggest edits (Github)
Contributors
1
Photo of the contributor
+ 1 contributors
On this page