300 APIs integrated in minutes, not days
Tags: api, javascript, webdev, node
Published: 2023-01-30 18:26:31

Software development is a great discipline. I've been a developer for over 10 years and have more fun at work than ever. Implementing something with a few lines of code, being able to try it out directly afterwards and being happy about the result is great. Personally, I enjoy the challenging things the most: figuring out how to solve a complex problem is incredibly satisfying.

Of course, there are also activities that are more of a means to an end. And this includes, among other things, the usage of (external) services in order to transmit information from A to B. Especially the interaction with APIs is part of every application nowadays. When a new product is developed, not every part of the value chain is implemented anew. To name a few examples:

- Sending messages via different channels (email, SMS, messenger, ...),
- Managing contacts or leads,
- Using location services,
- Connecting AI services,
- Connect CRM systems,
- And much, much more.

In each case, however, the same challenges exist:

- Understanding the data model of the service,
- Reading and understanding documentation,
- Understanding authentication,
- Understanding parameters,
- Making the first pass.

Believe it or not, it can take hours or even days to make the first breakthrough. And one anecdote is unfortunately also true: if you have already connected an API in the past, in most cases you have to go all the way again because most of it is no longer present.

As an additional dimension: do you use an SDK of the product (if available) or do you connect the API directly. At least with SDKs, you always have to ask yourself the questions:

- What dependencies are you getting into?
- Should I take a closer look at the SDK to verify that it does not do more than is necessary?
- Does the SDK have any vulnerabilities?

I have been building smaller to larger side projects for some time now. From my own experience I have to say I always ask myself the questions:

- How do I send another event to Mixpanel?
- How can I read data from Supabase?
- What is the payload to trigger a template from SendGrid?

It makes the development of new projects/products slow and inefficient. For this reason, I started to solve all the questions just mentioned, at least for me. A library that simplifies the connection of popular services to the maximum, brings no dependencies of its own, and only needs to be configured. No compromises. The result is flethy. A kit for connecting services. Even more has been created: the linking and execution of precisely these services.

There is always a lot that can be written, so let's make it concrete.

Add analytics event with [Mixpanel](https://mixpanel.com):

```ts
const config = nao<Mixpanel.TrackEvents>({
  kind: "mixpanel.events.track",
  "auth:token": "token",
  baseId: "api",
  "body:body": [
    {
      properties: {
        distinct_id: "distinctId",
        time: 0,
      },
      event: "signup",
    },
  ],
});
```

Get content from [ButterCMS](https://buttercms.com):

```ts
const config = nao<ButterCMS.GetMultiplePages>({
  kind: "buttercms.pages.getMultiple",
  "auth:auth_token": "token",
  "param:page_type": "pageSlug",
});
```

List articles from [Dev.to](https://dev.to):

```ts
const config = nao<DevTo.ListArticle>({
  kind: "devto.articles.list",
  "query:username": "username",
});
```

Create a new user at [Auth0](https://auth0.com):

```ts
const config = nao<Auth0.CreateUser>({
  kind: "auth0.users.create",
  "auth:Authorization": "token",
  "subdomain:tenant": "tenant",
  "body:email": "email",
  "body:family_name": "last",
  "body:given_name": "first",
});
```

The config object contains everything you need to fire the request against the API endpoint: `method`, `url`, `headers`, `body`. Now you can use your favorite http client to execute the real call (mine is fetch since it's available in both envs: browser and server).

The flethy connectors package is fully typed: you don't need to know how the payload is structured, what the URL for the specific use case is and which method has to be used.

Get started with flethy by just installing the package and then, yeah, select your favorite service to integrate!

```bash
npm i @flethy/connectors
# or
yarn add @flethy/connectors
# or
pnpm add @flethy/connectors
```

Try it out with [webhook.site](https://webhook.site):

```ts
import { nao, WebhookSite } from "@flethy/connectors";

const config = nao<WebhookSite.CoreGet>({
  kind: "webhooksite.core.get",
  "param:uuid": "your-individual-uuid",
  "header:x-test-header": "flethy",
});

console.log(config);
```

For me, that was not all. As a rule, it doesn't stay with just one step. I usually have several steps that have to be executed partly sequentially and partly in parallel. So why not merge the configurations together into one flow? Let's take the Authß Management API. I first need to get an access token to then interact with the API. What if it could then look like this?

```json
[
  {
    "id": "token",
    "config": {
      "namespace": "token"
    },
    "next": [
      {
        "id": "createUser"
      }
    ],
    "kind": "auth0.auth.accesstoken",
    "body:audience": "==>env==>AUTH0_AUDIENCE",
    "body:grant_type": "client_credentials",
    "body:client_id": "==>secrets==>AUTH0_CLIENT_ID",
    "body:client_secret": "==>secrets==>AUTH0_CLIENT_SECRET",
    "subdomain:tenant": "==>env==>AUTH0_TENANT"
  },
  {
    "id": "createUser",
    "config": {
      "namespace": "createUser"
    },
    "kind": "auth0.users.create",
    "auth:Authorization": "->context.token.access_token->string",
    "subdomain:tenant": "==>env==>AUTH0_TENANT",
    "body:email": "->context.input.email->string",
    "body:family_name": "->context.input.last->string",
    "body:given_name": "->context.input.first->string"
  }
]
```

Two steps are executed one after the other, the result from the first step is used in the second step. And as you can see, the description is a simple JSON. That means I'm programming language agnostic (what a word). Wohoo! So now how about just deploying this description to the cloud, and it will be executed there, and you don't have to worry about it yourself. And that's exactly what I'm working on right now. A first version is ready, a little fine-tuning is missing and then we can start.

The nice thing for me about this approach is that I can try everything out locally without any further dependencies before I deploy it to the cloud.

I'm looking forward to your feedback! And if you want to stay up to date, sign up at [flethy.com](https://flethy.com) and get regular news! And write to me if you are missing an integration!