Salta ai contenuti

API REST

Rebase genera automaticamente un’API completa dalle definizioni delle tue collezioni:

  • API REST — Endpoint CRUD per ogni collezione su /api/data/:slug
  • Specifica OpenAPI — Specifica leggibile dalla macchina su /api/docs
  • Swagger UI — Esploratore API interattivo su /api/swagger (solo in modalità sviluppo)

Non è richiesto alcun codice — definisci le tue collezioni e l’API appare automaticamente.

Per ogni collezione vengono generati i seguenti endpoint:

Metodo Percorso Descrizione
GET /api/data/:slug Elencare le entità
GET /api/data/:slug/count Contare le entità
GET /api/data/:slug/:id Ottenere una singola entità
POST /api/data/:slug Creare un’entità
PUT /api/data/:slug/:id Aggiornare un’entità
DELETE /api/data/:slug/:id Eliminare un’entità

Le relazioni annidate sono accessibili tramite percorsi URL:

GET /api/data/authors/42/posts → list author's posts
GET /api/data/authors/42/posts/7 → get a specific post by author
POST /api/data/authors/42/posts → create a post for author
PUT /api/data/authors/42/posts/7 → update the post
DELETE /api/data/authors/42/posts/7 → delete the post

Per gestire profondità arbitrarie di sottocollezioni annidate, Rebase instrada le richieste in arrivo usando la regex del parametro :rest{.+} di Hono. Il motore interno di analisi dei segmenti analizza i percorsi contando i segmenti separati da slash:

  • Numero dispari di segmenti (ad es. authors/42/posts -> 3 segmenti) rappresenta una richiesta di elenco di collezione.
  • Numero pari di segmenti (ad es. authors/42/posts/7 -> 4 segmenti) rappresenta un’operazione su un ID di entità specifico. L’ultimo segmento viene estratto come entityId target.

Il motore filtra i namespace di sistema riservati (ad es. history) dall’analisi dei segmenti del percorso per prevenire collisioni con gli endpoint integrati.

Tutti gli endpoint dei dati richiedono l’autenticazione per impostazione predefinita. Includi un token Bearer nell’header Authorization:

curl -H "Authorization: Bearer <access-token>" \
https://api.example.com/api/data/products

Per le chiamate server-to-server, usa la chiave di servizio:

curl -H "Authorization: Bearer <service-key>" \
https://api.example.com/api/data/products

Usa i parametri di query in stile PostgREST per filtrare i risultati. Il formato è ?field=operator.value:

# Exact match
GET /api/data/products?active=eq.true
# Comparison operators
GET /api/data/products?price=gt.100
GET /api/data/products?price=lte.50
# Multiple filters (AND)
GET /api/data/products?active=eq.true&price=gt.10
# IN operator — match any value in a set
GET /api/data/products?status=in.(draft,published)
# NOT IN
GET /api/data/products?status=nin.(archived,deleted)
# Array contains
GET /api/data/products?tags=cs.electronics
# Array contains any
GET /api/data/products?tags=csa.(electronics,books)
Operatore Significato Esempio
eq Uguale (==) ?active=eq.true
neq Diverso (!=) ?status=neq.draft
gt Maggiore di (>) ?price=gt.100
gte Maggiore o uguale (>=) ?price=gte.100
lt Minore di (<) ?price=lt.50
lte Minore o uguale (<=) ?price=lte.50
in In array ?status=in.(a,b,c)
nin Non in array ?status=nin.(a,b)
cs L’array contiene ?tags=cs.value
csa L’array contiene uno ?tags=csa.(a,b)

Usa or e and per condizioni complesse:

# OR: match products that are either cheap or on sale
GET /api/data/products?or=(price.lt.10,on_sale.eq.true)
# AND: explicit conjunction
GET /api/data/products?and=(active.eq.true,price.gt.0)

Usa orderBy con il formato field:direction:

# Sort by price descending
GET /api/data/products?orderBy=price:desc
# Sort by name ascending (default)
GET /api/data/products?orderBy=name:asc

Usa limit e offset, oppure page:

# Limit and offset
GET /api/data/products?limit=20&offset=40
# Page-based (uses default limit of 20)
GET /api/data/products?page=3

Il limite predefinito è 20, il massimo è 100.

Le risposte di elenco includono metadati di paginazione:

{
"data": [
{ "id": 1, "name": "Widget", "price": 29.99 },
{ "id": 2, "name": "Gadget", "price": 49.99 }
],
"meta": {
"total": 150,
"limit": 20,
"offset": 0,
"hasMore": true
}
}

Le risposte per una singola entità restituiscono un oggetto piatto:

{
"id": 1,
"name": "Widget",
"price": 29.99,
"created_at": "2026-01-15T10:30:00Z"
}

Usa searchString per la ricerca full-text sui campi di tipo stringa:

GET /api/data/products?searchString=wireless%20keyboard

Se una collezione definisce una proprietà di tipo vector, puoi eseguire ricerche di similarità ad alta velocità usando operazioni di distanza pgvector compilate direttamente nella query del database.

GET /api/data/products?vector_search=embedding&vector=[0.15,0.22,-0.05]&vector_distance=cosine&vector_threshold=0.8
Parametro Tipo Descrizione
vector_search string Il nome della proprietà vettoriale su cui eseguire la query.
vector string Un array di float serializzato in JSON che rappresenta il vettore di query.
vector_distance string La metrica di distanza da valutare. Valori supportati: cosine (predefinito, <=>), l2 (<->), inner_product (<#>).
vector_threshold number Soglia massima di distanza. Vengono restituiti solo i record con una distanza inferiore a questa soglia.

Usa il parametro include per incorporare le entità correlate:

# Include specific relations
GET /api/data/articles?include=author,categories
# Include all relations
GET /api/data/articles?include=*

Le relazioni incluse vengono incorporate direttamente nella risposta:

{
"id": 1,
"title": "Getting Started",
"author_id": 42,
"author": {
"id": 42,
"name": "Jane Doe",
"email": "jane@example.com"
}
}

Usa fields per selezionare colonne specifiche:

GET /api/data/products?fields=id,name,price

Ogni operazione di mutazione REST (POST, PUT, DELETE) attraversa una pipeline di esecuzione degli hook rigorosa e sequenziale:

Request ──► beforeSave/beforeDelete (blocking) ──► DB Operation ──► afterSave/afterDelete (deferred) ──► Response
  1. Hook bloccanti (beforeSave, beforeDelete) Questi hook vengono eseguiti in modo sincrono nel ciclo principale della richiesta prima di confermare la transazione del database. Possono modificare i payload in arrivo, eseguire validazioni personalizzate o interrompere completamente la richiesta generando un errore.

  2. Hook differiti (afterSave, afterDelete) Questi hook vengono eseguiti in modo asincrono dopo che la transazione del database è stata confermata con successo. Usano promise differite (fire-and-forget), il che significa che vengono eseguiti in background e non bloccano la risposta HTTP del client. Ideali per inviare webhook, attivare notifiche push o accodare attività esterne.

  • Specifica OpenAPI: GET /api/docs — Restituisce la specifica JSON OpenAPI 3.0 completa
  • Swagger UI: GET /api/swagger — Esploratore API interattivo (solo in modalità sviluppo)

La specifica OpenAPI viene generata automaticamente dalle definizioni delle tue collezioni e include tutti gli endpoint, i parametri di query e gli schemi di risposta.

Le chiavi API forniscono l’autenticazione machine-to-machine per agenti, server MCP, pipeline CI e integrazioni esterne. Supportano l’ambito dei permessi per collezione e l’accesso amministratore completo opzionale.

# Via CLI
rebase api-keys create --name "My Integration" \
--permissions '[{"collection":"orders","operations":["read","write"]}]'
# Via REST (requires admin auth)
curl -X POST http://localhost:3000/api/admin/api-keys \
-H "Authorization: Bearer <service-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "My Integration",
"permissions": [{ "collection": "orders", "operations": ["read", "write"] }]
}'

La risposta include la chiave completa in testo semplice (rk_live_...) esattamente una volta — memorizzala immediatamente.

curl http://localhost:3000/api/data/orders \
-H "Authorization: Bearer rk_live_abc123..."

La richiesta di una chiave API attraversa due controlli di autorizzazione, ed entrambi devono consentirla:

  1. L’elenco dei permessi della chiave — collezione × operazione, controllato a livello di route.
  2. Sicurezza a livello di riga — le chiavi API non bypassano la RLS. Una chiave viene eseguita come uid: "api-key:<id>" con il ruolo service (più admin quando admin: true). Le chiavi admin passano tramite le politiche admin integrate; una chiave non-admin vede solo le righe che una regola di sicurezza concede esplicitamente al ruolo service o al pubblico. Le regole in stile proprietario (owner_id = auth.uid()) non corrispondono mai a una chiave API.

Quindi una chiave non-admin con permessi "*" può comunque ottenere risultati vuoti — è la RLS che funziona, non un bug. Concedi il ruolo service nelle regole di sicurezza delle collezioni pertinenti, oppure usa una chiave admin.

Le invocazioni di funzioni hanno un ambito come le collezioni, sotto il namespace functions: {"collection": "functions", "operations": ["write"]} concede ogni funzione, "functions/<name>" ne concede una, e il carattere jolly globale "*" le concede tutte. Una chiave senza tale voce non può invocare funzioni affatto.

L’archiviazione funziona allo stesso modo, sotto il namespace storage: {"collection": "storage", "operations": ["read", "write"]} consente alla chiave di scaricare/elencare (read), caricare e creare cartelle (write), ed eliminare file (delete). Il carattere jolly globale "*" concede anche l’archiviazione. Una chiave senza tale voce non può toccare l’archiviazione. Le route di caricamento ripristinabile TUS contano come write a ogni passaggio (incluso il controllo dell’offset e l’annullamento), così una chiave con ambito di scrittura può completare un caricamento da sola.

Per impostazione predefinita, le chiavi API ottengono il ruolo service (solo accesso ai dati). Aggiungi "admin": true per concedere alla chiave l’accesso admin completo — incluse le route /api/admin/* per la gestione dello schema, la gestione degli utenti e altro ancora, più cron, backup e log. Usa questo per agenti, server MCP e CI:

# CLI
rebase api-keys create --name "My Agent" --admin --full-access
# REST
curl -X POST http://localhost:3000/api/admin/api-keys \
-H "Authorization: Bearer <service-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "My Agent",
"admin": true,
"permissions": [{ "collection": "*", "operations": ["read", "write", "delete"] }]
}'
Campo Tipo Descrizione
name string Etichetta leggibile dall’uomo
permissions ApiKeyPermission[] Accesso per collezione ("*" = tutto; "functions/<name>" = una funzione; "storage" = archiviazione file)
admin boolean Concedere il ruolo admin — route admin + politiche admin RLS
rate_limit number | null Richieste per finestra di 15 min (null = il valore predefinito del server, 1000)
expires_at string | null Timestamp di scadenza ISO-8601

La CLI richiede un ambito esplicito: passa --permissions '<json>' oppure scegli --full-access — non esiste un valore predefinito silenzioso di accesso completo.

Le chiavi possono essere elencate, aggiornate e revocate tramite /api/admin/api-keys o i comandi CLI rebase api-keys.

Ottieni un elenco di tutte le collezioni disponibili e della loro struttura:

GET /api/collections