How API Maker works¶
API Maker is a server you install, not a library you embed. Your apps call it over HTTP, it talks to your databases, and your own code, in TypeScript, Python, PHP, C#, Go, Rust, Java or Kotlin, runs beside it in sandboxes. This page shows the pieces once, so every other page makes sense.
The life of a request¶
- Your app calls a URL such as
GET /api/schema/admin/shop/main/customers?limit=10with the token of its API user inx-am-authorization. - Caddy (installed by the install script) ends HTTPS and forwards to API Maker on port
38246: the APIs and the WebSockets share that port. - Token and groups : API Maker checks the token, finds the API user and its groups, and refuses the call with
401(no valid token) or403(no group grants this API of this table). When the table asks for a person token too, that token is checked the same way. - Pre hooks you wrote for the instance, the database, the table or this API run in order. They can change the request, add a filter such as "only the rows of this person", answer directly, or throw.
- The API runs : a generated or schema API talks to the database, a custom API runs your function in the sandbox, a system API does its job. With caching on, the answer comes from Redis when it is there.
- Post hooks run with the result and can reshape it, notify, or throw.
- The reply goes back in the envelope
{ success, statusCode, data | errors }, as JSON, XML, YAML or text, with the key case you asked for in the headers. WebSocket subscribers of that API or table get their notification.
Every step is logged when a log profile selects the API, and counted in the analytics dashboard.
One base URL, several families¶
| Family | URL | What it is | Where it is described |
|---|---|---|---|
| Schema APIs | /api/schema/<user-path>/<instance>/<database>/<table>/… |
The operations of a table (17 on MongoDB, 14 on SQL tables), which apply the schema of the table | All APIs |
| Generated APIs | /api/gen/<user-path>/<instance>/<database>/<table>/… |
The same operations, without a schema | All APIs |
| Custom APIs | /api/custom-api/<user-path>/<your path> |
Your function, in any language, behind the path and method you choose | Custom APIs |
| System APIs | /api/system-api/<user-path>/<name> |
Ready made APIs : tokens, encryption, hashing, secrets, Redis keys, cache resets, events, indexes, validations | System APIs |
| Not over HTTP | Events, schedulers, WebSocket events, process initializers, migration scripts, hooks and test cases : code API Maker runs for you |
<user-path> is the API path of the admin or developer account which owns the item : admin for the first admin account. Each developer account has its own path, its own instances, secrets and code, on the same server.
The two tokens and the two gates¶
- The API user is an application : your web app, your mobile app, a partner. It is created on the API user permissions page, gets a token from the token API with its username and password, and sends it in
x-am-authorization. Its groups are the API gate : which APIs, tables and fields it may read and write. - The person is a row of your own users table, or a Google, Azure AD, AWS Cognito or custom identity. An auth provider turns it into a token sent in
x-am-user-authorization(or the header of the provider). Your code reads it ing.req.auth, and a pre hook is the row gate : it narrows every request to the rows of that person. - A new account starts with an API user named
default(password12345, kept in the default secret undercommon.apiUserPasswords.default) and a groupDefaultwhich allows everything. Replace both before you go live : one small group per screen is the pattern described in Handle role based permissions. - Public APIs (
apiAccessType: IS_PUBLICin the settings) skip both tokens.
Where your code runs¶
- The sandbox. Your code runs in Docker containers of its account, apart from the API Maker process. Each call gets a time to run : the one its item names (seconds for a custom API, minutes for a scheduler, an event listener, a migration script or a process initializer), else
13000ms. The headerx-am-sandbox-timeoutchanges it per call (time of a run). Custom APIs, hooks, event listeners, schedulers, migration scripts, process initializers, utility classes and test cases are written in any of the languages : TypeScript on Node.js or Bun, Python, PHP, C#, Go, Rust, Java or Kotlin. Each language has its own sandboxes, built from the runtime, version, packages and Dockerfile of the sandbox settings : nothing is installed that the account did not add. - The native process. A custom API with
runOnNativeProcess: trueruns on the machine of the server instead of in Docker, in one runner per runtime shared by every account (the runtime must be installed there :node,python3…), for the few cases that need it : a browser with Playwright, or the lowest possible latency. It is faster and less isolated. Like a sandbox, that runner answers what the code asks ofg.sysitself (the databases, Redis) and hands only the answer back to the server. - Settings run in the server. Code which only describes (the Basic Info of a custom API, the settings of APIs, schemas, the texts of internationalization, secrets) is TypeScript which API Maker runs itself, the moment you save it : what it exports is JSON for the database, so it needs no sandbox. It imports
typesand your utility classes written in TypeScript, no packages : where settings run. - The global object
g. Your code gets one object with the request (g.req), the response (g.res), every API of API Maker (g.sys.db,g.sys.system,g.sys.cache), a logger and a shared space, in every language : Global object g. - Code in the browser. You write the code in the admin panel : TypeScript with the types of API Maker (
import * as T from 'types') and the interfaces generated from your schemas (import * as db from 'db-interfaces'), or another language picked above the editor. Saving builds the code of compiled languages at once, and what does not compile is told in the console of the account. Or in your own editor, with the local client syncing the files both ways.
The servers¶
- API Maker is one process per server, run by systemd : systemd starts it when the server boots and again if it stops. Its threads use every core (one process, every core). Several servers behind Caddy form a cluster : schedulers are spread over the servers and run once per tick, a saved change and WebSocket notifications reach every server through Redis.
- MongoDB (a replica set) holds the data of API Maker itself : accounts, schemas, code, settings, logs. Your data stays in your databases.
- Redis holds the cache, the auto increment counters and what the servers of a cluster share.
- The admin panel is a static site that API Maker serves itself on a port of its own (
4626, theadminPanelsettings) : Caddy puts it on port80or on the domain you gave it. It talks to the same API, through an encrypted channel of its own. That channel keeps what the panel sends from whoever only listens on the way ; it does not prove to the browser that it is your server which answers. Only HTTPS does : give the install script a domain (Caddy then serves the panel and the API over HTTPS), or put a proxy with a certificate in front, before people rely on the installation. - Sandboxes : your code runs in Docker containers called sandboxes, one per language of an account. When one is busy, API Maker starts another, up to the sandbox count.
- Your databases can be on the same server or anywhere the server can reach. The connection strings live in the default secret.
The install page shows what the install script sets up ; the deployment architectures on the website go from one server to a global fleet.
What happens on a save¶
A write through a schema API is converted and checked before it reaches the database : keys not in the schema are refused, values get their types, strings are trimmed and cased, your conversionFun runs, fields are encrypted or hashed, ids and defaults are filled in, then the rules and your validatorFun decide. Everything wrong is answered at once, with 400 and one entry per problem, and nothing is saved. Table schema describes every option.
Everything is in Git¶
Schemas, settings, custom APIs, hooks, events, schedulers, utility classes, migrations, test cases and the security report are files in a Git repository. The admin panel commits and pushes them ; a Git pull on another server is the deployment. Secrets never go to Git. See Git integration and Deploy API Maker for the upgrade of API Maker itself.