Documentation
Feedback
Guides
App Development

App Development
ServicesCalling commerce APIs on VTEX IO
1. Getting the Service app boilerplate

To kickstart your journey in this course, your initial step is to clone the vtex.service-example boilerplate app. This repository serves as a template with all the essential files you need to get started in this course.

Cloning the boilerplate repository

Clone the vtex-apps/service-example boilerplate by running the command presented on the right panel. This will create a local copy of the project, equipping you with the necessary files to start the course.


_10
git clone https://github.com/vtex-apps/service-example

Understanding the project structure

Open the service-example project in the code editor of your preference. Note that the project contains the /node and /docs directories, the manifest.json file, and the package.json file.


_10
root
_10
┣ πŸ“‚ node
_10
┣ πŸ“‚ docs
_10
┣ πŸ“„ README.md
_10
┣ πŸ“„ manifest.json
_10
β”— πŸ“„ package.json

manifest.json file

At the heart of this structure lies the manifest.json file, a crucial document encapsulating metadata about the app. This file not only contains fundamental details such as the app's name, version, and title but also outlines the builders, policies, and dependencies necessary for the app functionality. Let's delve deeper into some of these concepts:

FieldTypeDescription
buildersobjectSpecifies the builders required by the app. Note that the app uses the node builder, responsible for interpreting Node.js code. For each declared builder, there will be a dedicated folder specifically designed to be interpreted by that particular builder.
policiesarrayDeclares policies for accessing external services or specific resources needed for the app functioning.
manifest.json

_34
{
_34
"name": "service-example",
_34
"vendor": "vtex",
_34
"version": "0.2.22",
_34
"title": "Service Example",
_34
"description": "Reference app for VTEX IO Services",
_34
"mustUpdateAt": "2018-01-04",
_34
"categories": [],
_34
"dependencies": {},
_34
"builders": {
_34
"node": "6.x",
_34
"docs": "0.x"
_34
},
_34
"scripts": {
_34
"prereleasy": "bash lint.sh"
_34
},
_34
"credentialType": "absolute",
_34
"policies": [
_34
{
_34
"name": "outbound-access",
_34
"attrs": {
_34
"host": "httpstat.us",
_34
"path": "*"
_34
}
_34
},
_34
{
_34
"name": "colossus-fire-event"
_34
},
_34
{
_34
"name": "colossus-write-logs"
_34
}
_34
],
_34
"$schema": "https://raw.githubusercontent.com/vtex/node-vtex-api/master/gen/manifest.schema"
_34
}

node folder

The /node folder contains the backend logic of the app, written in Node.js. Here, Node packages and native libraries, such as @vtex/clients, can be employed to enhance code development.

Within the node folder, you will also find the following folders and files:

Folder or fileDescription
/middlewaresFolder containing middleware functions.
/middlewares/validate.tsMiddleware that validates if the request has a valid HTTP status code. It will also be used to access the app authentication token.
/middlewares/status.tsMiddleware to call the VTEX Commerce API and fetch SKU details from the Catalog API.
/clientsFolder where the Clients of the app are defined, used to access external resources and services.
/clients/index.tsDefinition of the Clients class. Here we will import the Client Catalog and define a getter/setter function for Catalog items.
index.tsInitial declarations for the app's functionality, including mapping routes and middlewares.
package.jsonMetadata about the node app, including its name, version, description, dependencies, and scripts.
service.jsonConfiguration file that specifies the the app's infrastructure attributes. It includes details such as memory allocation, timeout duration, minimum and maximum replicas, and routes.
tsconfig.jsonConfiguration file for TypeScript, specifying how the TypeScript compiler should compile the project. It may include options such as the target JavaScript version, module system, and other compiler settings.
manifest.json

_12
node
_12
┣ πŸ“‚ middlewares
_12
┃ ┣ πŸ“„ validate.ts
_12
┃ β”— πŸ“„ status.ts
_12
┣ πŸ“‚ clients
_12
┃ ┣ πŸ“„ status.ts
_12
┃ β”— πŸ“„ index.ts
_12
┣ πŸ“„ index.ts
_12
┣ πŸ“„ package.json
_12
┣ πŸ“„ service.json
_12
┣ πŸ“„ tsconfig.json
_12
β”— πŸ“„ yarn.lock

node/service.json file

Located within the /node folder, the service.json file configures the app's infrastructure attributes. Key details are summarized in the following table:

FieldTypeDescription
memoryintegerMemory size allocated to the app, in megabytes. This value is subjective to automatic adjustments if excessive usage is detected.
timeoutintegerMaximum duration for fulfilling a request, in seconds. Requests exceeding this timeout are aborted.
minReplicasintegerMinimum number of replicas available when the app is operational.
maxReplicasintegerMaximum numbers of replicas available for the app.
routesobjectDescribes the app's REST routes. Note that a public route named status with the path /_v/status/:code is already defined.
manifest.json
node/service.json

_14
{
_14
"memory": 256,
_14
"ttl": 10,
_14
"timeout": 2,
_14
"minReplicas": 2,
_14
"maxReplicas": 4,
_14
"workers": 1,
_14
"routes": {
_14
"status": {
_14
"path": "/_v/status/:code",
_14
"public": true
_14
}
_14
}
_14
}

node/index.ts file

The node/index.ts file associates routes with middlewares. Note that the routes section associates the status route with the GET method and the validate and status middleware functions.

This means that when a GET request is made to the status route, the app will trigger the validate and status middleware functions in the specified order.

Check the middlewares/status.ts and middlewares/validate.ts files to better understand the functions exposed by this service.

manifest.json
node/service.json
node/index.ts

_56
import type { ClientsConfig, ServiceContext, RecorderState } from '@vtex/api'
_56
import { LRUCache, method, Service } from '@vtex/api'
_56
_56
import { Clients } from './clients'
_56
import { status } from './middlewares/status'
_56
import { validate } from './middlewares/validate'
_56
_56
const TIMEOUT_MS = 800
_56
_56
// Create a LRU memory cache for the Status client.
_56
// The 'max' parameter sets the size of the cache.
_56
// The @vtex/api HttpClient respects Cache-Control headers and uses the provided cache.
_56
// Note that the response from the API being called must include an 'etag' header
_56
// or a 'cache-control' header with a 'max-age' value. If neither exist, the response will not be cached.
_56
// To force responses to be cached, consider adding the `forceMaxAge` option to your client methods.
_56
const memoryCache = new LRUCache<string, any>({ max: 5000 })
_56
_56
metrics.trackCache('status', memoryCache)
_56
_56
// This is the configuration for clients available in `ctx.clients`.
_56
const clients: ClientsConfig<Clients> = {
_56
// We pass our custom implementation of the clients bag, containing the Status client.
_56
implementation: Clients,
_56
options: {
_56
// All IO Clients will be initialized with these options, unless otherwise specified.
_56
default: {
_56
retries: 2,
_56
timeout: TIMEOUT_MS,
_56
},
_56
// This key will be merged with the default options and add this cache to our Status client.
_56
status: {
_56
memoryCache,
_56
},
_56
},
_56
}
_56
_56
declare global {
_56
// We declare a global Context type just to avoid re-writing ServiceContext<Clients, State> in every handler and resolver
_56
type Context = ServiceContext<Clients, State>
_56
_56
// The shape of our State object found in `ctx.state`. This is used as state bag to communicate between middlewares.
_56
interface State extends RecorderState {
_56
code: number
_56
}
_56
}
_56
_56
// Export a service that defines route handlers and client options.
_56
export default new Service({
_56
clients,
_56
routes: {
_56
// `status` is the route ID from service.json. It maps to an array of middlewares (or a single handler).
_56
status: method({
_56
GET: [validate, status],
_56
}),
_56
},
_56
})

Testing the /status route

Change to the app directory and link it to a development workspace. This action will prompt the availability of the /status route. To verify its functionality, make a request to https://{workspace}--{accountName}.myvtex.com/_v/status/200, replacing {workspace} and {accountName} according to your scenario.

manifest.json
node/service.json
node/index.ts

_10
cd services-example && vtex link

Terminal

_44
20:00:48.027 - warn: Changing @vtex/api on devDependencies from 6.45.15 to 6.46.0
_44
20:00:48.029 - info: Running yarn in node
_44
yarn install v1.22.19
_44
warning package.json: No license field
_44
warning No license field
_44
[1/4] πŸ” Resolving packages...
_44
[2/4] 🚚 Fetching packages...
_44
[3/4] πŸ”— Linking dependencies...
_44
warning "@vtex/test-tools > react-intl@2.9.0" has unmet peer dependency "prop-types@^15.5.4".
_44
[4/4] πŸ”¨ Building fresh packages...
_44
success Saved lockfile.
_44
✨ Done in 38.02s.
_44
20:01:26.400 - info: Finished running yarn
_44
20:01:26.400 - info: Linking app vtex.service-example@0.2.22
_44
20:01:26.590 - info: Sending 14 files
_44
20:01:26.591 - info: Link ID: 0be90a2d772f711b
_44
20:01:26.592 - info: Project size: 0.49MB
_44
20:01:26.592 - info: Compressing project files...
_44
20:01:26.642 - info: Compressed project size: 0.21MB
_44
20:01:28.175 - info: Sending files: 100% - 0.21MB/0.21MB
_44
20:01:28.214 - info: Build accepted for vtex.service-example@0.2.22 at myaccount/myworkspace vtex.builder-hub@0.296.0
_44
20:01:28.488 - info: Starting build for app vtex.service-example@0.2.22 vtex.builder-hub@0.296.0
_44
20:01:42.645 - warn: node builder overrode the following options in tsconfig.json:
_44
module: 'esnext' => 'commonjs' vtex.builder-hub@0.296.0
_44
20:01:50.121 - info: Bundle: 17 files - 0.67MB vtex.builder-hub@0.296.0
_44
20:01:50.121 - info: Sent bundle to Apps in 688ms vtex.builder-hub@0.296.0
_44
20:01:50.121 - info: App linked successfully vtex.builder-hub@0.296.0
_44
20:01:50.122 - info: Node app build finished successfully vtex.builder-hub@0.296.0
_44
20:01:52.783 - info: Starting vtex.service-example@0.2.22 service-node@6.38.1
_44
20:01:52.783 - info: Fetching /apps/vtex.service-example@0.2.22/files/dist/service-node/dependencies.tar.zst service-node@6.38.1
_44
20:01:52.784 - info: Fetching /apps/vtex.service-example@0.2.22/bundle/dist/service-node/app service-node@6.38.1
_44
20:01:52.791 - info: OK: /apps/vtex.service-example@0.2.22/bundle/dist/service-node/app service-node@6.38.1
_44
20:01:52.792 - info: Extracted /apps/vtex.service-example@0.2.22/bundle/dist/service-node/app service-node@6.38.1
_44
20:01:52.830 - info: OK: /apps/vtex.service-example@0.2.22/files/dist/service-node/dependencies.tar.zst service-node@6.38.1
_44
20:01:52.866 - info: Extracted /apps/vtex.service-example@0.2.22/files/dist/service-node/dependencies.tar.zst service-node@6.38.1
_44
20:01:53.357 - info: Runtime @vtex/api is: /usr/local/app/node_modules/@vtex/api/lib/index.js service-node@6.38.1
_44
20:01:53.359 - info: Using @vtex/api from: /usr/local/app/node_modules/@vtex/api/lib/index.js service-node@6.38.1
_44
20:01:53.364 - info: Spawning 1 workers service-node@6.38.1
_44
20:01:53.368 - info: Using 30 seconds as worker graceful shutdown timeout service-node@6.38.1
_44
20:01:53.384 - info: Worker 25 is listening service-node@6.38.1
_44
20:01:53.878 - info: Available service routes:
_44
https://myworkspace--myaccount.myvtex.com/_v/status/:code service-node@6.38.1
_44
20:01:53.882 - info: App running service-node@6.38.1
_44
20:02:01.904 - info: Debugger tunnel listening on :9229. Go to chrome://inspect in Google Chrome to debug your running application.

Cloning the boilerplate repository

Clone the vtex-apps/service-example boilerplate by running the command presented on the right panel. This will create a local copy of the project, equipping you with the necessary files to start the course.

Understanding the project structure

Open the service-example project in the code editor of your preference. Note that the project contains the /node and /docs directories, the manifest.json file, and the package.json file.

manifest.json file

At the heart of this structure lies the manifest.json file, a crucial document encapsulating metadata about the app. This file not only contains fundamental details such as the app's name, version, and title but also outlines the builders, policies, and dependencies necessary for the app functionality. Let's delve deeper into some of these concepts:

FieldTypeDescription
buildersobjectSpecifies the builders required by the app. Note that the app uses the node builder, responsible for interpreting Node.js code. For each declared builder, there will be a dedicated folder specifically designed to be interpreted by that particular builder.
policiesarrayDeclares policies for accessing external services or specific resources needed for the app functioning.

node folder

The /node folder contains the backend logic of the app, written in Node.js. Here, Node packages and native libraries, such as @vtex/clients, can be employed to enhance code development.

Within the node folder, you will also find the following folders and files:

Folder or fileDescription
/middlewaresFolder containing middleware functions.
/middlewares/validate.tsMiddleware that validates if the request has a valid HTTP status code. It will also be used to access the app authentication token.
/middlewares/status.tsMiddleware to call the VTEX Commerce API and fetch SKU details from the Catalog API.
/clientsFolder where the Clients of the app are defined, used to access external resources and services.
/clients/index.tsDefinition of the Clients class. Here we will import the Client Catalog and define a getter/setter function for Catalog items.
index.tsInitial declarations for the app's functionality, including mapping routes and middlewares.
package.jsonMetadata about the node app, including its name, version, description, dependencies, and scripts.
service.jsonConfiguration file that specifies the the app's infrastructure attributes. It includes details such as memory allocation, timeout duration, minimum and maximum replicas, and routes.
tsconfig.jsonConfiguration file for TypeScript, specifying how the TypeScript compiler should compile the project. It may include options such as the target JavaScript version, module system, and other compiler settings.

node/service.json file

Located within the /node folder, the service.json file configures the app's infrastructure attributes. Key details are summarized in the following table:

FieldTypeDescription
memoryintegerMemory size allocated to the app, in megabytes. This value is subjective to automatic adjustments if excessive usage is detected.
timeoutintegerMaximum duration for fulfilling a request, in seconds. Requests exceeding this timeout are aborted.
minReplicasintegerMinimum number of replicas available when the app is operational.
maxReplicasintegerMaximum numbers of replicas available for the app.
routesobjectDescribes the app's REST routes. Note that a public route named status with the path /_v/status/:code is already defined.

node/index.ts file

The node/index.ts file associates routes with middlewares. Note that the routes section associates the status route with the GET method and the validate and status middleware functions.

This means that when a GET request is made to the status route, the app will trigger the validate and status middleware functions in the specified order.

Check the middlewares/status.ts and middlewares/validate.ts files to better understand the functions exposed by this service.

Testing the /status route

Change to the app directory and link it to a development workspace. This action will prompt the availability of the /status route. To verify its functionality, make a request to https://{workspace}--{accountName}.myvtex.com/_v/status/200, replacing {workspace} and {accountName} according to your scenario.


_10
git clone https://github.com/vtex-apps/service-example

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