VTEX Developer Portal

Using and creating clients

Introduction

Clients, on VTEX IO, are abstractions to other services. We tackle complexities when setting up an HTTP client, for example, so you can focus on the real value of your software. Whenever you need to setup a connection with an external API or another VTEX service, you should create a client! Some standard clients are already baked into VTEX IO, check them here.

Leave the burden with us!

These are some of the features built in our clients infrastructure:

  • Cache (you can use disk on in-memory cache easily)
  • Native metrics support
  • Retry and timeout options
  • Billing tracking (you can easily charge who uses your app)

Before talking about how we create clients, let’s recap how we use them. If you are familiar with IO services, you already know that your implementation exports functions that receive a context object. These functions can be a resolver function to a GraphQL field, a middleware to an HTTP server or an event handler, and, in all of them, you receive a ctx(or however you wanna call it) object of type [Context](https://github.com/vtex/node-vtex-api/blob/master/src/service/worker/runtime/typings.ts), and it is inside of ctx.clients where you’ll find each client.

export const authorize = async (ctx: Context) {
    const { clients: { licenseManager } } = ctx
    ...
    const data = await licenseManager.canAccessResource(/*...*/)
}

How to create clients and how do they look?

The [@vtex/api](https://github.com/vtex/node-vtex-api/) SDK provides a structured way to create clients, and the first thing to do is identify the type of communication you want to implement. As of now, we support these out of the box:

Type

Use case

AppClient

Communication with other IO Services via plain-old HTTP calls

AppGraphQLClient

Communication with other IO GraphQL services

ExternalClient

Communication with external API’s

JanusClient

Communication with VTEX Core Commerce API’s through Janus Router

InfraClient

Communication with VTEX IO Infra services

When using clients, don’t forget to add the appropriate policies on your manifest.json. Incorrect policies may result in request blocking.

After finding the base client you are looking for, you need to implement a Typescript class that extends the type of this base client. You may place them wherever you want, but we advise you to put them on node/clients.

Let’s take a look on the anatomy of an ExternalClient to the Github API:

node/clients/github.ts

Reference

  1. Look, it’s one of the types from the table above.
  2. Take a look here to check everything you can configure.
  3. Read more about app’s pricing here.
  4. There are a lot of other methods available, you can check them on [HttpClient].(https://github.com/vtex/node-vtex-api/blob/master/src/HttpClient/HttpClient.ts)

You’re free to add data handling logic inside your client’s methods (i.e: mapping fields, or filtering data), but be careful to not lose track of the client’s responsabilities!

Ok, now what?

After you’ve learned how to create great clients, it’s time to ship them, so you may use it on your implementations. It’s easy as well!

If you want to jump to an example, check how the StatusClient is setup on service-example.

Let’s suppose you’ve created the Github client we’ve described above!

  1. Make sure you’ve exported the client from its module. (Either default or named export)
  2. Create a node/clients/index.ts file.
  3. Paste the following snippet on it. (If you’ve used named export on Step 2, change the import clause)
import { IOClients } from '@vtex/api'
import GithubClient from './github.ts'

export class Clients extends IOClients {
  public get status() {
    return this.getOrSet('github', GithubClient)
  }
}

1 - Now, import the Clients class on node/index.ts (the service entrypoint).

2 - Create or edit a clients object of type ClientsConfig<Clients> (from @vtex/api) like so:

const clients: ClientsConfig<Clients> = {
      implementation: Clients,
      options: {
        default: {
          retries: 2,
          timeout: 2000,
        },
      },
    }

3 - Use the clients variable on the Service exported:

export default new Service<Clients, State>({
  clients,
  routes: {
    ...
  },
})

Optional: Place this type declaration on the same node/index.ts file. It helps you type the implementation functions.

declare global {
  type Context = ServiceContext<Clients, State>
}

That’s it ✨! Now you can, on your functions, access your client from the ctx.

export const authorize = async (ctx: Context) {
    const { clients: { github } } = ctx
    ...
    const data = await github.getUser(/*...*/)
}

Want to dive deeper?

If you didn’t find what you were looking for here, try learning by example. We are already doing some advanced thing on our default clients, like file upload, use of disk cache and more:

Updated 8 months ago


Using and creating clients


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.