Skip to main content

Develop

Root Item

The first thing we'll want to do is to expose the root of our graph. Every connector has a root item, which defines the entry point of its graph. This root item, having not been described by a schema, usually only defines relations. In our case, our root item will only link to one relation — our pokémons!

Open up the root handler (src/handlers/root.ts), and modify it as follow;

import { GetItemHandler, Api } from '@unito/integration-sdk';

export const getItem: GetItemHandler = async () => {
return {
fields: {},
relations: [
{
name: 'pokemons',
label: 'Pokémons',
path: '/pokemons',
schema: {
label: 'Pokémon',
fields: [
{
name: 'id',
label: 'Unique ID',
type: Api.FieldValueType.INTEGER,
},
{
name: 'name',
label: 'Name',
type: Api.FieldValueType.STRING,
},
{
name: 'base_experience',
label: 'Base experience',
type: Api.FieldValueType.NUMBER,
},
],
}
}
],
};
};

With that done, start the CLI (integration-cli dev), navigate to the debugger tab, and step into your first item!

Pokémons List

Alright, our root item specifies that we can find Pokémons at the /pokemons path, but we haven't coded that yet!

First, create a new pokemons handler (src/handlers/pokemons.ts), and modify it as follow;

import { GetCollectionHandler } from '@unito/integration-sdk';

export const getCollection: GetCollectionHandler = async () => {
return {
info: {},
data: [],
};
};

And then, open up the index file (src/index.ts) and modify it as follow;

import { Integration } from '@unito/integration-sdk';

import * as meHandler from './handlers/me.js';
import * as rootHandler from './handlers/root.js';
import * as pokemonsHandler from './handlers/pokemons.js';

const integration = new Integration();

integration.addHandler('/', rootHandler);
integration.addHandler('/me', meHandler);
integration.addHandler('/pokemons', pokemonsHandler);

integration.start();

Alright, now we can step into our root, and step again into our collection! It works, but it sadly sits empty for now. Let's add some Pokémons!

Provider

Create a new provider.ts (src/provider.ts) file and modify it as follow;

import { Provider } from '@unito/integration-sdk';

const provider = new Provider({
prepareRequest: _context => {
return {
url: 'https://pokeapi.co/api/v2',
headers: {}, // Here we would normaly provide the user's credentials in the provider's defined header of choice. Since the pokeapi is unauthenticated, we will leave empty
};
},
});

export default provider;

Now let's go back to our pokemons handler, and modify it as follow;

import { GetCollectionContext, GetCollectionHandler, HttpErrors } from '@unito/integration-sdk';

import provider from '../provider.js';

export const getCollection: GetCollectionHandler = async (context: GetCollectionContext<{}, { offset?: string }>) => {
const offset = Number(context.query.offset) || 0;
const limit = 100;

const response = await provider.get<{ next: string; results: { name: string }[] }>('/pokemon', {
...context,
queryParams: { limit: limit.toString(), offset: offset.toString() },
});

return {
info: {
nextPage: response.body.next ? `/pokemons?offset=${offset + limit}` : undefined,
},
data: response.data?.results.map(pokemon => ({
path: `/pokemons/${pokemon.name}`,
})),
};
};

Try again the CLI, and you should see a list of Pokémons!

Single Pokémon

The only thing missing now is a way to retrieve a single Pokémon. For this, we'll need two things.

First, open up index.ts (src/index.ts), we need to add a way for our handler's path to distingish between a collection and an individual item. This is done by adding a path identifier to our path.

import { Integration } from '@unito/integration-sdk';

import * as meHandler from './handlers/me.js';
import * as rootHandler from './handlers/root.js';
import * as pokemonsHandler from './handlers/pokemons.js';

const integration = new Integration();

integration.addHandler('/', rootHandler);
integration.addHandler('/me', meHandler);
integration.addHandler('/pokemons/:name', pokemonsHandler);

integration.start();

And finally, from within the same pokemons handler, add a new getItem property as follow;

import { GetCollectionContext, GetCollectionHandler, GetItemHandler, GetItemContext, HttpErrors } from '@unito/integration-sdk';

import provider from '../provider.js';

export const getCollection: GetCollectionHandler = async (context: GetCollectionContext<{}, { offset?: string }>) => {
const offset = Number(context.query.offset) || 0;
const limit = 100;

const response = await provider.get<{ next: string; results: { name: string }[] }>('/pokemon', {
...context,
queryParams: { limit: limit.toString(), offset: offset.toString() },
});

return {
info: {
nextPage: response.data.next ? `/pokemons?offset=${offset + limit}` : undefined,
},
data: response.data?.results.map(pokemon => ({
path: `/pokemons/${pokemon.name}`,
})),
};
};

export const getItem: GetItemHandler = async (context: GetItemContext<{ name: string }>) => {
const response = await provider.get<{
id: number;
name: string;
base_experience: number;
}>(`pokemon/${context.params.name}`, context);

return {
fields: {
id: response.data.id,
name: response.data.name,
base_experience: response.data.base_experience,
},
relations: [],
};
};

And with that, magically, we should be able to crawl all of our Pokémons!

image