APIBASE · Requêtes en chaîne APIBASE · Chained Queries

Chaîner. Filtrer. Résoudre.
Sans langage de requête lourd.
Chain. Filter. Resolve.
Without a query language.

Chaînez des appels API entre les tables. Filtrez sur n’importe quelle colonne. Résolvez les relations avec des pivots. Chaque résultat devient l’entrée de l’appel suivant — sans ORM, sans JOIN et sans requête illisible de 80 lignes.

Chain API calls across tables. Filter on any column. Resolve relations through pivots. Each result becomes the input of the next call — with no ORM and no JOIN. Complexity is distributed and readable — not concentrated in an 80-line query that only its author understands.

APIBASE est centré sur l’adresse, pas sur la requête. SQL tente souvent d’exprimer toute la réponse dans une seule déclaration. APIBASE prend une autre route : découvrir le schéma, adresser des coordonnées T/L/C exactes, exécuter de petits appels déterministes, puis composer le résultat dans le code. Chaque requête peut cibler sa propre table, colonne, opérateur et valeur. APIBASE is address-centric, not query-centric. SQL usually tries to express the whole answer as one declarative statement. APIBASE takes another route: discover the schema, address exact T/L/C coordinates, run small deterministic calls, then compose the result in code. Each request can target its own table, column, operator, and value.
Les exemples sont écrits en PHP. Les mêmes appels fonctionnent dans n’importe quel langage — il suffit d’un client HTTP et d’un bearer token. Examples are written in PHP. The same calls work in any language — all you need is an HTTP client and a bearer token.
Modèle 1Pattern 1

Requêtes en cascadeCascading queries

Chaque appel API alimente le suivant. Filtrez une table, prenez les IDs du résultat, puis interrogez une deuxième table avec ces IDs. Pas de syntaxe JOIN — seulement des appels HTTP en séquence.

Each API call feeds the next. Filter a table, take the ids from the result, query a second table with those ids. No JOIN syntax — just HTTP calls in sequence.

Deux phases. La phase 1 appelle /schema une fois par table pour extraire les IDs T et C. La phase 2 utilise ces constantes pour chaîner les requêtes à l’exécution.

Two phases. Phase 1 calls /schema once per table to extract T and C ids. Phase 2 uses those constants to chain queries at request time.

// PHASE 1 — setup: discover T and C once
$eq  = api_get("$api/hive/schema/$base/equipements", $token);
$ord = api_get("$api/hive/schema/$base/orders", $token);

$T_equipements = $eq['T'];
$C_type = array_flip($eq['columns'])['type'];

$T_orders = $ord['T'];
$C_equipement_id = array_flip($ord['columns'])['equipement_id'];

// PHASE 2 — equipment where type contains "pump"
$equipements = api_get(
  "$api/hive/get/$base/T{$T_equipements}/L/C{$C_type}/O28?V=pump&format=assoc",
  $token
)['data'];

// for each equipment → its orders
foreach ($equipements as $equi) {
  $orders = api_get(
    "$api/hive/get/$base/T{$T_orders}/L/C{$C_equipement_id}/O1?V={$equi['id_equipement']}&format=assoc",
    $token
  )['data'];
}
Modèle 2Pattern 2

Filtrage multi-niveauxMulti-level filtering

Filtrez sur une colonne, extrayez une valeur du résultat, puis utilisez-la pour filtrer la table suivante. Chaque niveau réduit le jeu de données.

Filter on any column using an operator. Take the matching records, extract a value, use it as the filter for the next table. Each level narrows the dataset.

Opérateur utilisé ici : O1 égale. Le nom du site est résolu avec une adresse directe L{$id}. Operator used here: O1 equals. The site name is resolved with a direct line address L{$id}.
// active orders → unique site ids → resolve site names
$orders = api_get(
  "$api/hive/get/$base/T{$T_orders}/L/C{$C_status}/O1?V=active&format=assoc",
  $token
)['data'];

$siteIds = array_unique(array_column($orders, 'site_id'));

foreach ($siteIds as $id) {
  $site = api_get(
    "$api/hive/get/$base/T{$T_sites}/L{$id}/C{$C_site}?format=raw",
    $token
  )['data'];
}
Modèle 3Pattern 3

Résolution par table pivotPivot table resolution

Les relations plusieurs-à-plusieurs sont stockées dans une table pivot : deux colonnes de clés étrangères, une ligne par lien. On interroge le pivot, puis on résout chaque clé étrangère séparément.

Many-to-many relations are stored in a pivot table — two foreign key columns, one row per link. Resolve them by querying the pivot, then resolving each foreign key independently.

// equipement 5 → pivot equipementtags → tags
$links = api_get(
  "$api/hive/get/$base/T{$T_equipementtags}/L/C{$C_equipement_id}/O1?V=5&format=assoc",
  $token
)['data'];

foreach ($links as $link) {
  $label = api_get(
    "$api/hive/get/$base/T{$T_tags}/L{$link['tag_id']}/C{$C_tag}?format=raw",
    $token
  )['data'];
}
Modèle 3 — étenduPattern 3 — extended

Le pivot comme source de statistiquesPivot as a stats source

Une table pivot n’est pas seulement un pont : c’est aussi un journal d’activité interrogeable. Filtrez-la directement par FK pour calculer des statistiques sans toucher aux tables liées.

A pivot table is not just a bridge between two entities — it is also a queryable activity log. Filter it directly by one FK to get all the stats for that entity without touching the related tables.

// reservations for client 12 — one call, no cascade
$reservations = api_get(
  "$api/hive/get/$base/T{$T_reservations}/L/C{$C_client_id}/O1?V=12&format=assoc",
  $token
)['data'];

$nb_stays      = count($reservations);
$room_ids      = array_column($reservations, 'room_id');
$unique_rooms  = array_unique($room_ids);
$frequencies   = array_count_values($room_ids);
$favorite_room = array_search(max($frequencies), $frequencies);
Un seul appel API. Pas de cascade vers clients. Pas de cascade vers rooms. One API call. No cascade to clients. No cascade to rooms.
Modèle 4Pattern 4

Découverte dynamique par agent IAAI agent runtime discovery

Un agent IA peut construire toute la cascade à l’exécution. Il appelle /schema, mappe les noms de colonnes vers les IDs C, puis construit la requête dynamiquement.

An AI agent can build the full cascade at runtime. It calls /schema first, maps column names to C ids, then constructs the query dynamically.

Comme les adresses TLC sont déterministes et énumérables, l’agent trouve une coordonnée valide ou retourne une erreur — jamais une supposition.

Because TLC addresses are deterministic and enumerable, the agent either finds a valid coordinate or returns an error — never a guess.

$schema = api_get("$api/hive/schema/$base/equipements", $token);
$T_equipements = $schema['T'];
$cols = array_flip($schema['columns']);

$C_type = $cols['type'];

$rows = api_get(
  "$api/hive/get/$base/T{$T_equipements}/L/C{$C_type}/O28?V=pump&format=assoc",
  $token
)['data'];
Modèle 5Pattern 5

OR multi-colonnesMulti-column OR

APIBASE supporte un filtre par appel. Pour chercher dans plusieurs colonnes, faites un appel par colonne, puis fusionnez et dédupliquez par clé primaire.

APIBASE supports one filter per call. To search the same table on multiple columns simultaneously, make one call per column then merge and deduplicate by primary key.

Règle : array_merge + déduplication par PK = OR. Intersection = AND. Rule: array_merge + dedup by PK = OR. Intersection = AND.
$byClient = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_client}/O28?V=dupont&format=assoc", $token)['data'];
$byCity   = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_city}/O28?V=dupont&format=assoc", $token)['data'];
$byEmail  = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_email}/O28?V=dupont&format=assoc", $token)['data'];

$seen = $result = [];
foreach (array_merge($byClient, $byCity, $byEmail) as $row) {
  if (!isset($seen[$row['id_client']])) {
    $seen[$row['id_client']] = true;
    $result[] = $row;
  }
}
Modèle 6Pattern 6

Union entre tablesCross-table union

Cherchez la même valeur dans plusieurs tables — clients, contacts, fournisseurs. Chaque appel cible une table différente. Une étiquette _type est ajoutée avant la fusion pour conserver l’origine.

Search the same value across multiple tables — clients, contacts, suppliers. Each call targets a different table. A _type tag is added before the merge so every row carries its origin.

Contrairement à SQL, les tables n’ont pas besoin d’exposer les mêmes colonnes ni de suivre la même forme.

Unlike SQL, the tables do not need to expose the same columns or follow the same shape.

$clients  = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_client}/O28?V=dupont&format=assoc", $token)['data'];
$contacts = api_get("$api/hive/get/$base/T{$T_contacts}/L/C{$C_contact}/O28?V=dupont&format=assoc", $token)['data'];
$suppliers = api_get("$api/hive/get/$base/T{$T_suppliers}/L/C{$C_supplier}/O28?V=dupont&format=assoc", $token)['data'];

foreach ($clients as &$row)  { $row['_type'] = 'client'; }
foreach ($contacts as &$row) { $row['_type'] = 'contact'; }
foreach ($suppliers as &$row) { $row['_type'] = 'supplier'; }

$all = array_merge($clients, $contacts, $suppliers);
Modèle 7Pattern 7

Résolution FK — LEFT JOINFK resolution — LEFT JOIN

Quand une table contient déjà une clé étrangère, récupérez les lignes, extrayez les valeurs FK uniques, résolvez chacune une seule fois avec L{id}, puis hydratez les résultats.

When a table already contains a foreign key, fetch all rows, extract the unique FK values, resolve each one once with a direct L{id} call, then hydrate inline.

$orders = api_get("$api/hive/get/$base/T{$T_orders}/L?format=assoc", $token)['data'];

$unique_client_ids = array_unique(array_column($orders, 'client_id'));
$client_names = [];

foreach ($unique_client_ids as $id) {
  $client_names[$id] = api_get(
    "$api/hive/get/$base/T{$T_clients}/L{$id}/C{$C_client}?format=raw",
    $token
  )['data'];
}

foreach ($orders as &$order) {
  $order['client_name'] = $client_names[$order['client_id']];
}
Modèle 8Pattern 8

Requêter dans les archivesQuerying across archives

Chaque table APIBASE possède un segment actif et des archives en lecture seule (aaa, aab, aac…). Ajouter &archive= cible un segment précis.

Each APIBASE table has an active chunk and a series of read-only archive chunks (aaa, aab, aac…). Adding &archive= targets a specific chunk.

Les IDs ne collisionnent jamais. Les clés primaires sont continues entre les segments. IDs never collide. Primary keys are continuous across all chunks.
$clients_now = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_client}/O28?V=dupont&format=assoc", $token)['data'];
$clients_aaa = api_get("$api/hive/get/$base/T{$T_clients}/L/C{$C_client}/O28?V=dupont&format=assoc&archive=aaa", $token)['data'];

foreach ($clients_now as &$r) { $r['_era'] = 'now'; }
foreach ($clients_aaa as &$r) { $r['_era'] = 'aaa'; }

$all = array_merge($clients_now, $clients_aaa);

Prêt à construire ?Ready to build?

Récupérez votre schéma, stockez vos IDs T et C, puis commencez à chaîner les appels. La collection contient tous les endpoints prêts à tester.

Get your schema, store your T and C ids, start chaining calls. The collection has all endpoints ready to test.