API Maker

The framework for AI era

Your code

Events & WebSockets

React to API calls with your own listeners, and push live updates to web and mobile apps.

An event runs a list of TypeScript listeners after an API call, or when your code emits it. WebSocket events go the other way: apps subscribe to an API with a condition, and API Maker notifies the matching ones after each successful call. The caller always gets its response first.

See it live

Step through it, slow it down, or open the full canvas.

api-maker/features/events-managementLive
  • Request
  • Event
  • Done
  • Stopped
Events run
0in this tour
Listeners
0run in order
Loops
0stopped
Notifications
0sent

The response first, then the events. An event can run on every call of an API: generated, custom or system. The caller gets its response first, the event gets that response as its data.

How it works

  1. The response first, then the events.

    An event can run on every call of an API: generated, custom or system. The caller gets its response first, the event gets that response as its data.

  2. Listeners run one after another.

    Each listener is TypeScript run in the sandbox, with its own timeout. It reads the data in g.req.eventData: send a receipt, update the stock, call any API.

  3. Events can emit events.

    Any code can run a custom event with g.sys.system.emitEvent, with its data and, if you want, only some of its listeners. Workflows grow step by step.

  4. A loop is stopped at once.

    API Maker keeps the chain of events of each call. An event that is already in it is not run again, the caller gets the chain in the error.

  5. Clients subscribe over WebSocket.

    A web or mobile app registers for an API, a table and a condition on the response, and gets an eventId. It can unregister at any time.

  6. Only matching clients are notified.

    After each successful call, the registrations whose condition matches the response get the event data. No notification when a pre hook throws.

What you get

Listeners in order

An event holds listeners that run one after another, each with its own time limit, in the sandbox or on the native process. They read the data in g.req.eventData.

Triggered by any API

Attach an event to generated, custom or system APIs: it runs after every call, with the response as its data.

Emitted from code

g.sys.system.emitEvent(name, data, listeners) runs an event from any code, all its listeners or only the ones you name.

No endless loops

API Maker keeps the chain of events of each call. An event already in the chain is not run again, and the error shows the chain.

Live updates over WebSocket

Apps connect with their tokens and register for an API, a table, a custom API or a custom WebSocket event. Each registration gets an eventId to unregister later.

Only what matters

A condition on the response picks which calls notify a client, and select picks the fields it receives.

An example

A live kitchen screen

When an order is saved, an event records a notification for the customer and sends the receipt email, while the screens of the kitchen, registered for the orders of their store, show the new order at once.

A listener of the event order-paidlistener.ts
import * as T from 'types';async function main(g: T.IAMGlobal) {    const order = g.req.eventData;    await g.sys.db.saveSingleOrMultiple({        instance: 'mongodb', database: 'shop', collection: 'notifications',        saveData: { customer_id: order.customer_id, text: `Order ${order._id} is paid.` },    });}module.exports = main;
A web app registers for new orders of one storeapp.ts
const ws = new WebSocket(`wss://ws.example.com/?x-am-authorization=${token}`);ws.onopen = () => ws.send(JSON.stringify({    objType: 'REGISTER',    onEvents: [{        eventType: 'INSTANCES',        apiName: 'SCHEMA_POST_BULK_INSERT',        instance: 'mongodb', database: 'shop', collection: 'orders',        condition: { conditionType: 'RESPONSE', criteria: { store_id: 7 } },        select: { _id: 1, total: 1 },        getEventData: true,    }],}));ws.onmessage = message => console.log(JSON.parse(message.data)); // NOTIFICATION with eventData

First create the WebSocket event of this API in API Maker. API Maker listens for WebSockets on port 38245; the installer puts it behind Caddy, which serves it as wss.

Good to know

  • A WebSocket condition compares flat values of the response: nested objects are not supported in its criteria.
  • No notification is sent for a call that fails before its response, for example when a pre hook throws.
  • Events run after the response, so they can not change it. Use a post hook for that.

Questions

Do events slow down my APIs?

No. The response is written first. Events, WebSocket notifications and logs run after it.

Can a WebSocket client connected to one server get events from another server?

Yes. Registrations are kept in Redis, so the server that runs the API finds the clients to notify.

Can I decide who may connect?

Yes. A WebSocket event has its auth providers and a "can user connect" function that returns whether the user can register, and the error text if not.