In this guide, you will learn how to create clients and how to use them in your implementations.
Before you start
- Being familiar with the concept of Clients
So, what to do with clients? You create them, extending some base code. IO Node Services already ship with some default clients, mostly to our internal services, that you may use right away. Check them here.
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
, 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(/*...*/)
}
Creating clients
- The
@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, do not 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.
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.
Using clients on implementations
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!
- Make sure you've exported the client from its module. (Either default or named export)
- Create a
node/clients/index.ts
file. - 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)
}
}
- Now, import the Clients class on
node/index.ts
(the service entrypoint). - Create or edit a
clients
object of typeClientsConfig<Clients>
(from @vtex/api) like so:
const clients: ClientsConfig<Clients> = {
implementation: Clients,
options: {
default: {
retries: 2,
timeout: 2000,
},
},
}
- 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: