Supabase 兼容接口

2026-10-20

Supabase 兼容接口

(待译)

Database exposes its row API through Supabase client paths. Use a base URL ending in /supabase/<database_id>/, including the trailing slash, and a Praxis credential. Unlike Supabase, storage uses SQLite; define tables and fields through /database/v1, not SQL migrations, and do not expect Supabase Auth, RLS policies or realtime subscriptions. Auth, storage, realtime, functions and graphql service paths return 501 with x-should-retry=false. See the Database domain for supported concepts and differences.

使用官方 supabase-js 读写一个库中的表。

指南 →

基础地址

https://api.deepraxis.ai/supabase/{database_id}/

部分含义
{database_id}建库返回的 ID;每个库使用自己的地址。
/保留末尾斜杠,supabase-js 才会保留库 ID 并追加 rest/v1。

API Key 用作 Authorization: Bearer 凭据;supabase-js 的第二个参数传同一 Key。以下示例在服务端运行。

import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  `https://api.deepraxis.ai/supabase/${process.env.DATABASE_ID}/`,
  process.env.PRAXIS_API_KEY,
  { auth: { persistSession: false, autoRefreshToken: false } },
);

表端点

GET / HEAD / POST / PATCH / DELETE

/supabase/{database_id}/rest/v1/{table}

仅提供下列 PostgREST 子集。不支持的语法返回 HTTP 400,code 为 PGRST127;无效或未知参数可能返回 PGRST100。

过滤运算符

值支持情况
eq支持
neq支持
gt支持
gte支持
lt支持
lte支持
like支持
ilike支持
in支持
is支持
cs支持
cd支持
ov支持
fts不支持
plfts不支持
phfts不支持
wfts不支持
match不支持
imatch不支持
isdistinct不支持
sl不支持
sr不支持
nxl不支持
nxr不支持
adj不支持

Prefer

值支持情况
return=minimal支持
return=headers-only支持
return=representation支持
count=exact支持
count=planned部分支持
count=estimated部分支持
resolution=merge-duplicates支持
resolution=ignore-duplicates支持
missing=default部分支持
handling=strict支持
handling=lenient支持

Accept

值支持情况
application/json支持
*/*支持
application/vnd.pgrst.object+json支持
text/csv不支持
application/geo+json不支持
application/vnd.pgrst.plan*不支持

查询语法

值支持情况
not支持
and/or/not.and/not.or支持
JSON paths (->, ->>)支持
aliases支持
link embedding支持
!field hint支持
embedded filters/order/pagination不支持
casts (::)不支持
aggregates不支持
spread (...)不支持
!inner/!left不支持
operator(any)/operator(all)不支持

planned/estimated 当前返回精确计数;字段可以配置 default:批量插入中有的行提供、有的行缺失的列,带 missing=default 时缺失处取字段 default,否则按 PostgREST 写 null;所有行都未提供的列始终取 default(没有 default 时为 null)。cs/cd/ov 接收数组({a,b} 或 ["a"]);json 字段上的 cs/cd 还接受 JSON 对象,按 jsonb 包含判断,例如 meta=cs.{"color":"red"}(键值逐层包含);cs 还接受 JSON 标量,数组顶层含该元素即匹配,例如 meta=cs."a"。cs.{}/cd.{} 在 json 字段上是空对象,在数组字段上是空数组。一次 DELETE 删除的行之间互相引用不阻断删除,只要有引用者不在本次删除中就返回 409 23503。like/ilike 只适用于 string 字段与 ->> 文本路径,用在其他类型返回 400 42883。字符串按二进制序(区分大小写,大写在小写前)比较与排序,不支持按 lower() 排序;需要不区分大小写排序时,另存一个小写字段并按它排序。GET/HEAD 带 If-None-Match 且与当前 ETag 匹配时返回 304、无正文。不支持的 Accept 返回 406 PGRST107。upsert 仅接受 id 或单个 unique 字段。

Prefer 中的未知值默认忽略;handling=strict 时返回 400 PGRST122。单对象 Accept 恰好匹配一行时返回对象,否则返回 406 PGRST116。 其他不支持的 Accept 返回 406 PGRST107。

未开放服务

路径HTTPcode
/supabase/{database_id}/auth/v1/{+path}501not_implemented
/supabase/{database_id}/storage/v1/{+path}501not_implemented
/supabase/{database_id}/realtime/v1/{+path}501not_implemented
/supabase/{database_id}/functions/v1/{+path}501not_implemented
/supabase/{database_id}/graphql/v1/{+path}501not_implemented

这些服务返回 x-should-retry: false。它们的错误体与表端点不同,只有 code 和 message。

错误码表与错误体

读写行

指南 →

/supabase/{database_id}/rest/v1/{table}

与同一库的其它入口读写相同的行;错误使用 PostgREST code。

支持矩阵与初始化

参数与请求头

名称位置说明
database_idpath库 ID。
tablepath表 ID 或名称。
selectquery列名列表;支持 *、别名、JSON 路径及 link 关联展开。不支持类型转换、聚合、展开运算和连接修饰。
{column}query把 {column} 换为字段名或 JSON 路径,例如 title=eq.summary;不同列的条件同时生效。
andquery括号内的条件全部成立,例如 (done.eq.false,title.neq.draft)。
orquery括号内任一条件成立。
not.andquery否定全部条件成立。
not.orquery否定任一条件成立。
orderquery逗号分隔的字段,可带 asc/desc、nullsfirst/nullslast;支持 JSON 路径。
limitquery最多返回的条数。
offsetquery跳过的行数。
on_conflictqueryupsert 的冲突键:id 或单个 unique 字段;配合 Prefer 的 resolution。
columnsquery写入列的逗号分隔列表;列表之外的输入键被忽略。
RangeheaderGET/HEAD 的闭区间,例如 0-9;与 limit/offset 取交集。
Range-Unitheaderitems;其它单位使 Range 被忽略。
Preferheader逗号分隔的偏好。未知值默认被忽略;handling=strict 时返回 400 PGRST122。
Acceptheaderapplication/json、/ 或 application/vnd.pgrst.object+json;单对象模式必须恰好匹配一行,否则返回 406 PGRST116。其他媒体类型返回 406 PGRST107;text/csv、application/geo+json 与 application/vnd.pgrst.plan 返回 400 PGRST127。
If-None-Matchheader上次 GET/HEAD 返回的 ETag(弱比较);与当前 ETag 匹配时返回 304,无正文。

POST 接受单个对象或对象数组;PATCH 接受对象。系统列由服务管理。写入默认不返回正文,使用 Prefer: return=representation(SDK 的 .select())返回行。PATCH 和 DELETE 只影响匹配过滤器的行;省略过滤器会影响全部匹配行。

响应头说明
Content-Range本次行范围/总数;未请求计数时总数为 *。
Preference-Applied已应用的偏好。
ETagGET/HEAD 返回的版本标记;请求带 If-None-Match 且与之匹配时返回 304、无正文。
LocationPOST 使用 return=headers-only 时的新行地址。

读取通常为 200;请求计数且只返回部分行时为 206。POST 为 201。PATCH/DELETE 使用 representation 时为 200,否则为 204。HEAD 没有正文。If-None-Match 与当前 ETag 匹配时返回 304。datetime 值统一按 UTC、3 位毫秒保存和读出(如 2026-10-11T00:30:00.000Z),精度为毫秒,超过 3 位的小数秒四舍五入。

查询行

GET /supabase/{database_id}/rest/v1/{table}

const { data, error } = await supabase.from("tasks").select("*").order("title").limit(10);
if (error) throw error;
console.log(data);

响应

HTTP 200

Success; write bodies require Prefer: return=representation

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

HTTP 206

Partial range with requested count

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

响应示例 — HTTP 200

响应头值
content-range0-0/*
etagW/"5.1"
range-unititems
[
  {
    "id": "rec_e88fcbd357aa49c9",
    "version": 1,
    "created_at": "2026-10-11T17:42:00.094Z",
    "updated_at": "2026-10-11T17:42:00.094Z",
    "title": "Write a summary",
    "done": false
  }
]

统计行

HEAD /supabase/{database_id}/rest/v1/{table}

const { data, error, count } = await supabase.from("tasks").select("*", { head: true, count: "exact" });
if (error) throw error;
console.log(count);

响应

HTTP 200

Success; write bodies require Prefer: return=representation

未声明响应体。

HTTP 206

Partial range with requested count

未声明响应体。

响应示例 — HTTP 200

响应头值
content-range0-0/1
preference-appliedcount=exact
etagW/"5.1"
range-unititems

无响应正文。

插入行

POST /supabase/{database_id}/rest/v1/{table}

const { data, error } = await supabase.from("tasks").insert({"title":"Write a summary","done":false}).select();
if (error) throw error;
console.log(data);

响应

HTTP 201

Success; write bodies require Prefer: return=representation

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

响应示例 — HTTP 201

响应头值
content-range0-0/*
preference-appliedreturn=representation
range-unititems
[
  {
    "id": "rec_e88fcbd357aa49c9",
    "version": 1,
    "created_at": "2026-10-11T17:42:00.094Z",
    "updated_at": "2026-10-11T17:42:00.094Z",
    "title": "Write a summary",
    "done": false
  }
]

更新行

PATCH /supabase/{database_id}/rest/v1/{table}

const { data, error } = await supabase.from("tasks").update({ done: true }).eq("title", "Write a summary").select();
if (error) throw error;
console.log(data);

响应

HTTP 200

Success; write bodies require Prefer: return=representation

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

HTTP 204

Success without a body

未声明响应体。

响应示例 — HTTP 200

响应头值
content-range0-0/*
preference-appliedreturn=representation
range-unititems
[
  {
    "id": "rec_e88fcbd357aa49c9",
    "version": 2,
    "created_at": "2026-10-11T17:42:00.094Z",
    "updated_at": "2026-10-11T17:42:01.047Z",
    "title": "Write a summary",
    "done": true
  }
]

合并行

POST /supabase/{database_id}/rest/v1/{table}

const { data, error } = await supabase.from("tasks").upsert({"title":"Write a summary","done":true}, { onConflict: "title" }).select();
if (error) throw error;
console.log(data);

响应

HTTP 201

Success; write bodies require Prefer: return=representation

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

响应示例 — HTTP 201

响应头值
content-range0-0/*
preference-appliedresolution=merge-duplicates, return=representation
range-unititems
[
  {
    "id": "rec_e88fcbd357aa49c9",
    "version": 3,
    "created_at": "2026-10-11T17:42:00.094Z",
    "updated_at": "2026-10-11T17:42:01.735Z",
    "title": "Write a summary",
    "done": true
  }
]

删除行

DELETE /supabase/{database_id}/rest/v1/{table}

const { data, error } = await supabase.from("tasks").delete().eq("title", "Write a summary").select();
if (error) throw error;
console.log(data);

响应

HTTP 200

Success; write bodies require Prefer: return=representation

application/json

名称类型说明
[].idstring
[].versioninteger
[].created_atstring
[].updated_atstring

application/vnd.pgrst.object+json

名称类型说明
idstring
versioninteger
created_atstring
updated_atstring

HTTP 204

Success without a body

未声明响应体。

响应示例 — HTTP 200

响应头值
content-range0-0/*
preference-appliedreturn=representation
range-unititems
[
  {
    "id": "rec_e88fcbd357aa49c9",
    "version": 3,
    "created_at": "2026-10-11T17:42:00.094Z",
    "updated_at": "2026-10-11T17:42:01.735Z",
    "title": "Write a summary",
    "done": true
  }
]