API REST
Panoramica
Sezione intitolata “Panoramica”Rebase genera automaticamente un’API completa dalle definizioni delle tue collection:
- API REST — Endpoint CRUD per ogni collection su
/api/data/:slug - Specifica OpenAPI — Specifica leggibile da macchina su
/api/docs - Swagger UI — Explorer API interattivo su
/api/swagger(solo in modalità di sviluppo)
Non è richiesto alcun codice — definisci le tue collection e l’API apparirà automaticamente.
Endpoint REST
Sezione intitolata “Endpoint REST”Per ogni collection vengono generati i seguenti endpoint. Tutte le altre route montate dal backend — auth, storage, admin, meta — si trovano nell’endpoint index.
| Metodo | Percorso | Descrizione |
|---|---|---|
GET |
/api/data/:slug |
Elenca le entità |
GET |
/api/data/:slug/count |
Conta le entità |
GET |
/api/data/:slug/aggregate |
count(), sum(), avg(), min(), max(), opzionalmente raggruppati. Accetta gli stessi filtri dell’endpoint di elenco e la RLS si applica alle righe aggregate — vedi Querying |
GET |
/api/data/:slug/:id |
Recupera una singola entità |
POST |
/api/data/:slug |
Crea un record |
PATCH |
/api/data/:slug/:id |
Aggiorna un record (parziale — vengono scritte solo le proprietà inviate) |
DELETE |
/api/data/:slug/:id |
Elimina un record |
POST |
/api/data/:slug/bulk |
Crea molteplici entità in un’unica transazione |
PATCH |
/api/data/:slug/bulk |
Aggiorna molteplici entità in un’unica transazione |
POST |
/api/data/:slug/bulk/delete |
Elimina molteplici entità in un’unica transazione |
POST |
/api/data/_batch |
Scrive tra collection diverse in un’unica transazione |
Route di subcollection
Sezione intitolata “Route di subcollection”Le relazioni annidate sono accessibili tramite percorsi URL:
GET /api/data/authors/42/posts → list author's postsGET /api/data/authors/42/posts/7 → get a specific post by authorPOST /api/data/authors/42/posts → create a post for authorPATCH /api/data/authors/42/posts/7 → update the postDELETE /api/data/authors/42/posts/7 → delete the postMeccanica di routing e parsing dei segmenti
Sezione intitolata “Meccanica di routing e parsing dei segmenti”Per gestire livelli arbitrari di annidamento delle subcollection, Rebase instrada le richieste in arrivo utilizzando la regex del parametro :rest{.+} di Hono. Il motore interno di parsing dei segmenti analizza i percorsi contando i segmenti separati da slash:
- Conteggio segmenti dispari (es.
authors/42/posts-> 3 segmenti) rappresenta una richiesta di elenco di una collection. - Conteggio segmenti pari (es.
authors/42/posts/7-> 4 segmenti) rappresenta un’operazione su un ID di entità specifico. L’ultimo segmento viene estratto comeentityIddi destinazione.
Il motore esclude i namespace di sistema riservati (es. history) dall’analisi dei segmenti di percorso per evitare collisioni con gli endpoint predefiniti.
Autenticazione
Sezione intitolata “Autenticazione”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/productsPer le chiamate server-to-server, utilizza la chiave di servizio (service key):
curl -H "Authorization: Bearer <service-key>" \ https://api.example.com/api/data/productsFiltraggio
Sezione intitolata “Filtraggio”Utilizza i parametri di query in stile PostgREST per filtrare i risultati. Il formato è ?field=operator.value:
# Exact matchGET /api/data/products?active=eq.true
# Comparison operatorsGET /api/data/products?price=gt.100GET /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 setGET /api/data/products?status=in.(draft,published)
# NOT INGET /api/data/products?status=nin.(archived,deleted)
# Array containsGET /api/data/products?tags=cs.electronics
# Array contains anyGET /api/data/products?tags=csa.(electronics,books)Operatori di filtro
Sezione intitolata “Operatori di filtro”| Operatore | Significato | Esempio |
|---|---|---|
eq |
Uguale a (==) |
?active=eq.true |
neq |
Diverso da (!=) |
?status=neq.draft |
gt |
Maggiore di (>) |
?price=gt.100 |
gte |
Maggiore o uguale a (>=) |
?price=gte.100 |
lt |
Minore di (<) |
?price=lt.50 |
lte |
Minore o uguale a (<=) |
?price=lte.50 |
in |
Nell’array | ?status=in.(a,b,c) |
nin |
Non nell’array | ?status=nin.(a,b) |
cs |
L’array contiene | ?tags=cs.value |
csa |
L’array contiene almeno uno | ?tags=csa.(a,b) |
like |
Corrispondenza di pattern, con distinzione tra maiuscole e minuscole (like) |
?sku=like.AB-% |
ilike |
Corrispondenza di pattern, senza distinzione tra maiuscole e minuscole (ilike) |
?name=ilike.%widget% |
nlike |
Non corrisponde al pattern (not-like) |
?sku=nlike.TMP-% |
nilike |
Non corrisponde, senza distinzione tra maiuscole e minuscole (not-ilike) |
?name=nilike.%test% |
isnull |
La colonna è NULL (is-null) |
?deleted_at=isnull.null |
notnull |
La colonna non è NULL (is-not-null) |
?deleted_at=notnull.null |
isnull e notnull ignorano il rispettivo valore — l’operatore costituisce l’intera condizione e qualsiasi cosa dopo il punto viene scartata. L’SDK scrive .null, quindi è questa la dicitura che vedrai transitare in rete.
Operatori logici
Sezione intitolata “Operatori logici”Usa or, and e not per condizioni complesse:
# OR: match products that are either cheap or on saleGET /api/data/products?or=(price.lt.10,on_sale.eq.true)
# AND: explicit conjunctionGET /api/data/products?and=(active.eq.true,price.gt.0)
# NOT: everything that is not a discontinued in-stock itemGET /api/data/products?not=(discontinued.eq.true,stock.gt.0)not nega la congiunzione delle sue condizioni: not(a) equivale a NOT a, e not(a,b) a NOT (a AND b). Viene compilato in un vero NOT (...) SQL anziché in operatori invertiti — la logica SQL è a tre valori, quindi NOT (a AND b) e (NOT a) OR (NOT b) smettono di coincidere non appena entra in gioco un NULL. Una negazione quindi include le righe la cui colonna è NULL, che è ciò che significa NOT; aggiungi un notnull in AND se non è questo il comportamento desiderato.
Un solo gruppo per richiesta: or prevale su and, ed entrambi prevalgono su not. Sono tre formulazioni dello stesso slot, non tre filtri separati. Usa invece l’annidamento:
GET /api/data/products?or=(price.lt.10,and(active.eq.true,price.gt.0))GET /api/data/products?not=(or(status.eq.draft,status.eq.archived))I gruppi possono essere annidati fino a 32 livelli di profondità; oltre questo limite la richiesta viene rifiutata con INVALID_LOGICAL_GROUP.
Un gruppo restringe i risultati insieme ai filtri di campo anziché sostituirli — vedi Come si combinano i filtri.
Il dialetto JSON where
Sezione intitolata “Il dialetto JSON where”I filtri di campo sopra descritti sono uno dei due modi per inviare un filtro. L’altro consiste in un singolo oggetto JSON, che è ciò che il documento OpenAPI pubblica su ogni GET /api/data/{slug} e ciò che accettano le route di subcollection annidate:
GET /api/data/products?where={"status":["==","active"],"price":[">=",100]}Ogni chiave è un campo, ogni valore è una tupla canonica [operator, value] — le stesse tuple scritte dall’SDK. Un valore può anche essere una stringa con notazione a punto pre-serializzata ({"status":"eq.active"}) o uno scalare semplice ({"status":"active"}); tutte e tre le varianti compilano nella stessa condizione.
La differenza fondamentale da conoscere: JSON trasporta i tipi. ?price=gte.100 invia la stringa "100" e il driver ne effettua il cast in base al tipo di colonna, mentre ?where={"price":[">=",100]} invia un numero. Per una colonna la cui interpretazione testuale e numerica differisce — una stringa di versione, un codice con padding di zeri — questo è il parametro a cui affidarsi.
Un where malformato restituisce un errore 400 INVALID_WHERE, e non un filtro ignorato silenziosamente: scartarlo significherebbe eseguire la lettura senza filtri e restituire tutto ciò che la row-level security consente di leggere.
Come si combinano i filtri
Sezione intitolata “Come si combinano i filtri”?field=op.value, ?where=, ?or=/?and= e ?searchString= sono indipendenti, e ciascuno di essi presente deve corrispondere:
(field filters and `where`, AND-ed together) AND (the logical group) AND (the search string)Non c’è modo di applicare l’operatore OR tra questi gruppi. Qualsiasi condizione che non sia un semplice AND di questi gruppi deve essere inserita all’interno di un unico albero or=/and=.
Ordinamento
Sezione intitolata “Ordinamento”Usa orderBy con il formato field:direction:
# Sort by price descendingGET /api/data/products?orderBy=price:desc
# Sort by name ascending (default)GET /api/data/products?orderBy=name:ascUna direzione mancante equivale a asc. Una direzione che non sia né asc né desc, oppure un campo non presente nella collection, restituisce un errore 400 — non un 200 con le righe ordinate arbitrariamente dal database, il che sarebbe indistinguibile da un ordinamento riuscito.
Più chiavi di ordinamento
Sezione intitolata “Più chiavi di ordinamento”La sintassi abbreviata supporta una sola chiave. Per utilizzarne più di una, passa un array JSON — la seconda chiave discrimina tra le righe considerate uguali dalla prima:
# By category, and newest first within each categoryGET /api/data/products?orderBy=[{"field":"category"},{"field":"createdAt","direction":"desc"}]Entrambe le formulazioni sono supportate da tutte le route che elencano righe, incluse quelle annidate (/api/data/authors/:id/posts). Ogni ordinamento termina sull’id di riga decrescente, sia che venga richiesto o meno: questo è ciò che rende l’ordinamento totale, e la paginazione su un ordinamento non totale ripete e salta righe.
Un parametro ?orderBy= ripetuto non costituisce un ordinamento a più chiavi — l’ultimo specificato prevale, come accade per ogni altro parametro di query. Usa l’array.
Posizionamento dei valori NULL nell’ordinamento
Sezione intitolata “Posizionamento dei valori NULL nell’ordinamento”Per impostazione predefinita, i valori NULL vengono ordinati per ultimi in ordine crescente e per primi in ordine decrescente, seguendo la convenzione nativa di Postgres. Un terzo segmento separato da due punti permette di specificare diversamente:
# Newest first, with the undated rows at the end rather than the topGET /api/data/posts?orderBy=publishedAt:desc:lastIl formato ad array JSON accetta una chiave "nulls" per la stessa funzionalità:
GET /api/data/posts?orderBy=[{"field":"publishedAt","direction":"desc","nulls":"last"}]Qualsiasi valore diverso da first o last genera un 400, e non un ordine silenziosamente differente. Il cursore descritto di seguito rispetta quanto dichiarato dall’ordinamento, garantendo che la paginazione su una chiave che ammette valori null rimanga corretta con entrambe le impostazioni.
Paginazione
Sezione intitolata “Paginazione”Usa limit e offset, oppure page:
# Limit and offsetGET /api/data/products?limit=20&offset=40
# Page-based (uses the default limit of 50)GET /api/data/products?page=3Il limite predefinito è 50, il massimo è 1000. Entrambi provengono da DEFAULT_LIST_LIMIT / MAX_LIST_LIMIT, valori riportati anche nella specifica OpenAPI generata — un limit superiore al massimo viene rifiutato anziché ridotto al limite (clamped).
Tutti e tre i parametri della finestra vengono rifiutati anziché corretti automaticamente, e ciascuno specifica il proprio codice: INVALID_LIMIT, INVALID_OFFSET (un numero intero maggiore o uguale a 0) e INVALID_PAGE (un numero intero maggiore o uguale a 1). Una finestra silenziosamente diversa da quella richiesta non potrebbe essere distinta dal raggiungimento della fine della collection, motivo per cui nessuno di essi viene limitato o ignorato.
Paginazione tramite cursore
Sezione intitolata “Paginazione tramite cursore”offset riconta le righe a ogni richiesta; pertanto, una riga inserita o eliminata tra due pagine sposta la finestra e la scansione salta o ripete silenziosamente delle righe. ?after= esegue invece una ricerca diretta (seek): la pagina successiva inizia tassativamente dopo l’ultima riga restituita.
Ogni risposta di elenco include meta.nextCursor finché è disponibile un’altra pagina. Rinvialo invariato:
GET /api/data/orders?orderBy=createdAt:desc&limit=100# → meta.nextCursor = "eyJrIjpbWyJjcmVhdGVkX2F0Iiw…"
GET /api/data/orders?orderBy=createdAt:desc&limit=100&after=eyJrIjpbWyJjcmVhdGVkX2F0Iiw…Il cursore è opaco — codifica le chiavi di ordinamento e i valori dell’ultima riga per tali chiavi — da cui derivano tre regole, ciascuna delle quali genera un errore 400 anziché restituire una pagina errata:
| Situazione | Codice |
|---|---|
after con offset o page |
CURSOR_WITH_OFFSET — entrambi specificano l’inizio della pagina |
after con un orderBy diverso da quello con cui è stato emesso |
CURSOR_ORDER_MISMATCH |
| Un cursore non emesso da questa API | INVALID_CURSOR |
Una richiesta che non specifica alcun orderBy adotta quello del cursore, pertanto rinviare meta.nextCursor senza ripetere l’ordinamento funziona correttamente.
Gli ordinamenti a più chiavi e le chiavi con valori null paginano entrambi correttamente: il confronto viene costruito su ciascuna chiave in sequenza, rispettando il posizionamento dei valori NULL dichiarato nell’ordinamento. L’unico ordinamento che nessun cursore può descrivere è la pertinenza (_score) — calcolata per ogni query e non memorizzata da nessuna parte — e tale elenco semplicemente non include alcun nextCursor.
Selezione delle colonne
Sezione intitolata “Selezione delle colonne”?fields= restringe la lettura alle sole colonne indicate. Si tratta di una proiezione inserita direttamente nella query, non di un ritaglio della risposta:
GET /api/data/posts?fields=id,title&limit=50La chiave primaria viene sempre restituita (una riga che non può essere indirizzata non può essere aggiornata, eliminata o superata con la paginazione — e il cursore è derivato da essa), e le colonne con excludeFromApi rimangono nascoste indipendentemente dal fatto che vengano specificate o meno. Una colonna sconosciuta restituisce un 400 UNKNOWN_FIELD anziché una riga priva silenziosamente del campo.
?distinct=true raggruppa le righe identiche rispetto a tali colonne:
# The statuses actually in useGET /api/data/posts?fields=status&distinct=trueViene rifiutato (400) in combinazione con un searchString con punteggio di pertinenza o con una ricerca vettoriale, che associano un punteggio per ciascuna riga rendendo ogni riga distinta per definizione, e quando orderBy indica una colonna non restituita da fields (DISTINCT_ORDER_BY_NOT_SELECTED) — Postgres non può ordinare una lettura DISTINCT tramite un’espressione esclusa dalla propria clausola select.
?fields= e ?distinct= funzionano anche sulla route get-by-id e sulle route di subcollection annidate.
Formato della risposta
Sezione intitolata “Formato della risposta”Le risposte di elenco includono i 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, "nextCursor": "eyJrIjpbWyJpZCIsImRlc2MiXV0sInYiOnsiaWQiOjJ9LCJpIjoyfQ" }}nextCursor è presente finché hasMore è true e la pagina ha restituito almeno una riga; è assente nell’ultima pagina e con ordinamenti che nessun cursore può descrivere.
Le risposte per una singola entità restituiscono un oggetto semplice (flat):
{ "id": 1, "name": "Widget", "price": 29.99, "createdAt": "2026-01-15T10:30:00Z"}Ogni errore, proveniente da qualsiasi route, viene restituito in una struttura (envelope) unificata:
{ "error": { "message": "Unknown filter operator 'contains' on field 'title'.", "code": "UNKNOWN_FILTER_OPERATOR", "details": { "field": "title", "operator": "contains" }, "requestId": "9f1c0b8e-4d2a-4e1b-9d0f-2c7a5b3e6a11" }}message e code sono sempre presenti. details compare quando il rifiuto riguarda un elemento specifico — il campo non valido, i percorsi non riusciti. requestId compare quando la richiesta conteneva un header X-Request-ID o ne è stato assegnato uno; viene riportato anche nell’header della risposta ed è il riferimento da indicare nelle segnalazioni di bug.
Crea ramificazioni condizionali su code, mai su message o sul solo status code. I codici sono in SCREAMING_SNAKE_CASE e stabili; i messaggi sono pensati per una persona che legge una console e possono variare. Lo status HTTP si trova sulla risposta, non nel corpo.
| Stato | Codice tipico | Significato |
|---|---|---|
| 400 | BAD_REQUEST, VALIDATION_ERROR, INVALID_LIMIT, INVALID_OFFSET, INVALID_PAGE |
La richiesta è malformata o richiede un’operazione impossibile |
| 401 | UNAUTHORIZED |
Nessuna credenziale, o credenziale che non identifica nessuno |
| 403 | FORBIDDEN, DB_PERMISSION_DENIED |
Credenziale che identifica un utente privo dei permessi necessari |
| 404 | NOT_FOUND |
L’elemento indirizzato non esiste |
| 409 | CONFLICT |
Conflitto di stato — una chiave duplicata, un albero dirty |
| 501 | varia | La funzionalità esiste ma non è configurata in questo deployment |
| 503 | SERVICE_UNAVAILABLE |
Una dipendenza non è raggiungibile; la richiesta non l’ha mai raggiunta |
Una superficie/funzionalità assente perché non abilitata in questo deployment risponde con 501 accompagnato da un codice e da una motivazione, non con 404 — un 404 inspiegato su una route appena invocata dalla UI verrebbe interpretato come un deploy non funzionante.
Le route aggiungono i propri codici più specifici oltre a questi (EMAIL_EXISTS, TOKEN_EXPIRED, UNKNOWN_FILTER_OPERATOR, …), quindi considera l’elenco dei codici come aperto. L’SDK client converte tutti gli errori in un unico RebaseApiError contenente status, code e details — vedi Error handling.
Ricerca testuale
Sezione intitolata “Ricerca testuale”Usa searchString per la ricerca full-text nei campi stringa:
GET /api/data/products?searchString=wireless%20keyboardRicerca vettoriale
Sezione intitolata “Ricerca vettoriale”Se una collection definisce una proprietà di tipo vector, puoi eseguire ricerche per similarità ad alta velocità utilizzando le operazioni di distanza di 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.8Parametri di query vettoriale
Sezione intitolata “Parametri di query vettoriale”| 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 distanza inferiore a questa soglia. |
Inclusione delle relazioni
Sezione intitolata “Inclusione delle relazioni”Usa il parametro include per incorporare le entità correlate:
# Include specific relationsGET /api/data/articles?include=author,categories
# Include all relations, one hop deepGET /api/data/articles?include=*
# A relation of a relation — up to three hopsGET /api/data/articles?include=comments.authorUn nome che non corrisponde a una relazione della collection genera un errore 400 UNKNOWN_RELATION, a qualsiasi livello. In precedenza veniva ignorato, rispondendo con 200 e lasciando semplicemente mancante il campo — un comportamento indistinguibile da una riga priva di record correlati, facendo apparire un errore di battitura esattamente come dati vuoti. Un percorso con più di tre passaggi (hop) genera INCLUDE_TOO_DEEP.
Limitare una relazione
Sezione intitolata “Limitare una relazione”Il formato separato da virgole non consente di specificare un limit per singola relazione; pertanto, include accetta anche JSON — riconoscibile dalla parentesi graffa iniziale:
GET /api/data/posts?include={"comments":{"limit":5,"where":{"published":["==",true]},"orderBy":"createdAt:desc","fields":["id","body"],"include":{"author":true}}}| Chiave | Significato |
|---|---|
limit |
Righe per riga genitore, non sull’intera pagina |
where |
Lo stesso dialetto di filtro utilizzato dal where di primo livello |
logical |
Un gruppo or/and/not sulle righe correlate |
orderBy |
La stessa sintassi di ordinamento, inclusa la posizione dei valori NULL |
fields |
Colonne della riga correlata; la sua chiave viene sempre preservata |
include |
A sua volta, relazioni della riga correlata |
true significa “carica l’entità per intero”, quindi {"author":true} e author rappresentano la medesima richiesta. Entrambe le formulazioni funzionano sulla route di elenco, sulla route get-by-id e sulle route di subcollection annidate.
Ogni hop corrisponde a una query raggruppata (batched) per l’intera pagina, mai a una query per ciascuna riga.
Le relazioni incluse vengono incorporate direttamente nella risposta:
{ "id": 1, "title": "Getting Started", "authorId": 42, "author": { "id": 42, "name": "Jane Doe", "email": "jane@example.com" }}Scrittura
Sezione intitolata “Scrittura”Chiavi di idempotenza, scritture condizionali (ETag / If-Match), operazioni sui campi ($inc, $push, $pull, $merge), upsert su chiave naturale, Prefer: return=minimal e l’endpoint multi-collection POST /api/data/_batch sono tutti trattati in una pagina dedicata: Writing over REST.
Pipeline degli hook del ciclo di vita
Sezione intitolata “Pipeline degli hook del ciclo di vita”Su Postgres, ogni mutazione REST (POST, PATCH, DELETE) esegue in ordine i callback della sua collezione, dentro l’unica transazione che porta la scrittura:
Request ──► BEGIN ──► beforeSave/beforeDelete ──► DB operation ──► afterSave/afterDelete ──► COMMIT ──► ResponseOgni hook viene atteso, e un errore lanciato da uno qualsiasi di essi annulla l’intera scrittura:
beforeSave,beforeDeletevengono eseguiti prima della scrittura. Possono modificare i valori in ingresso, validare o rifiutare la richiesta lanciando un errore: il chiamante riceve 400CALLBACK_REJECTEDe non viene scritto nulla.afterSave,afterDeletevengono eseguiti dopo la scrittura ma prima del commit. Un errore annulla la riga e risponde con lo stesso 400, condetails.stageche indica l’hook. Tengono aperta la transazione mentre sono in esecuzione, quindi non sono il posto per un webhook o per qualsiasi altra chiamata di rete: Hooks spiega dove va quel lavoro.
Endpoint di sistema
Sezione intitolata “Endpoint di sistema”| Metodo | Percorso | Autenticazione | Descrizione |
|---|---|---|---|
GET |
/health and /api/health |
nessuna | Verifica di liveness/readiness |
GET |
/api/docs |
nessuna | La specifica JSON di OpenAPI 3.0 |
GET |
/api/swagger |
nessuna | Swagger UI. Attivo in fase di sviluppo, disattivato in produzione; REBASE_ENABLE_SWAGGER ne sovrascrive lo stato in entrambi i casi |
GET |
/api/meta/schema-version |
nessuna | L’hash dello schema da cui è stato compilato questo backend — deliberatamente non autenticato, restituisce solo tale hash |
GET |
/api/meta/contract |
admin, service key o admin API key | Il contratto completo delle collection, per rebase generate-sdk --from. Fail-closed: 404 se non è configurata alcuna autenticazione |
GET |
/metrics |
REBASE_METRICS_TOKEN quando impostato |
Metriche di Prometheus, se REBASE_METRICS=true |
OpenAPI / Swagger
Sezione intitolata “OpenAPI / Swagger”La specifica OpenAPI viene generata automaticamente a partire dalle definizioni delle tue collection: descrive gli endpoint di elenco, lettura, creazione, aggiornamento, eliminazione e operazioni di massa (bulk) di ogni collection gestita dal backend, con i rispettivi parametri di query e schemi di risposta. Non costituisce una mappa completa dell’intera superficie HTTP — le route relative ad auth, storage, functions e cron sono documentate esclusivamente su questo sito — e le colonne contrassegnate con excludeFromApi ne vengono escluse.
I client automatizzati (machine callers) si autenticano mediante una chiave con permessi dedicati (scoped key) anziché tramite una sessione: API keys.
Metadati dello schema
Sezione intitolata “Metadati dello schema”Lo schema completo delle collection del progetto — ogni collection, proprietà e relazione — viene fornito a un amministratore autenticato:
GET /api/meta/contractÈ accessibile solo agli amministratori e, su un deployment privo di autenticazione configurata, non viene restituito affatto (404 CONTRACT_UNAVAILABLE) anziché esporre lo schema pubblicamente. Il suo endpoint complementare restituisce una stringa di versione che identifica lo schema senza descriverlo ed è deliberatamente accessibile senza alcuna credenziale — ed è ciò su cui esegue il polling un job di CI:
GET /api/meta/schema-versionPer verificare la struttura degli endpoint anziché lo schema sottostante, il documento OpenAPI è disponibile su GET /api/docs, con la Swagger UI consultabile su /api/swagger quando enableSwagger è abilitato.
Passaggi successivi
Sezione intitolata “Passaggi successivi”- Client SDK — Client con tipizzazione statica per l’API REST
- Collections — Definisci lo schema dei tuoi dati
- Security Rules (RLS) — Controlla l’accesso per singola riga