PostgREST 从建表到 REST API 上线:4 层实操指南
2026/9/5 14:54:07 网站建设 项目流程

PostgREST 从建表到 REST API 上线:4 层实操指南

【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest

PostgREST 把 PostgreSQL 的表、视图和函数直接变成 RESTful API,你不用写一行路由代码。这篇实操指南带你走完 4 步:跑通最小实例、看懂它的角色与权限体系、配好关键参数、完成生产加固。适合第一次接触这个项目、准备把它用在真实业务里的开发者。

1. 3 分钟拉通最小实例

目标:一个能返回数据的 REST 端点。

1.1 用 Docker 把数据库和 PostgREST 都拉起来

两个容器就够:一个 PostgreSQL,一个 PostgREST。

# docker-compose.yml version: '3' services: server: image: postgrest/postgrest ports: - "3000:3000" environment: PGRST_DB_URI: postgres://authenticator:mysecret@db:5432/postgres db: image: postgres ports: - "5432:5432" environment: POSTGRES_DB: postgres POSTGRES_USER: authenticator POSTGRES_PASSWORD: mysecret

PGRST_DB_URI是 PostgREST 唯一必须知道的配置:它用这个连接串去连数据库。官方镜像基于 scratch 构建,总大小约 14MB,里面只有一个静态二进制。

1.2 建一张表,配一个最小配置文件

进容器建一张todos表,并创建两个角色:web_anon(匿名请求用)和登录角色authenticator

CREATE SCHEMA api; CREATE TABLE api.todos ( id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, done boolean NOT NULL DEFAULT false, task text NOT NULL ); INSERT INTO api.todos (task) VALUES ('finish tutorial 0'); CREATE ROLE web_anon NOLOGIN; GRANT USAGE ON SCHEMA api TO web_anon; GRANT SELECT ON api.todos TO web_anon; CREATE ROLE authenticator NOINHERIT LOGIN PASSWORD 'mysecret'; GRANT web_anon TO authenticator;

注意最后一行:GRANT web_anon TO authenticator是后面角色切换的基础,漏了它请求会直接 401。

配置文件只需 3 行:

# postgrest.conf db-uri = "postgres://authenticator:mysecret@localhost:5432/postgres" db-schemas = "api" db-anon-role = "web_anon"

db-schemas决定哪些 schema 会暴露成接口,db-anon-role指定没带身份的请求用哪个角色执行。

1.3 验证端点,404 时先查 schema cache

postgrest postgrest.conf # 输出:Starting PostgREST ... # Successfully connected to PostgreSQL ... # API server listening on port 3000

另开一个终端请求它:

curl http://localhost:3000/todos # 输出:[{"id":1,"done":false,"task":"finish tutorial 0"}]

看到 JSON 数组说明通了。⚠️ 注意:如果你重启 PostgREST 之后新建了表,请求会 404。因为 PostgREST 启动时会把表结构缓存进 schema cache(模式缓存),不会实时发现新对象。在 psql 里执行NOTIFY pgrst;触发重载,再请求就正常了。

1.4 试写操作,观察权限如何生效

curl -X POST http://localhost:3000/todos \ -H "Content-Type: application/json" \ -d '{"task": "do bad thing"}'

返回 401 和"permission denied for table todos"。这不是配置错误——web_anon只有SELECT权限。PostgREST 的安全模型在下一节展开。

2. 看懂它的角色与权限体系

2.1 三种角色各管什么

PostgREST 用 PostgreSQL 的 role(角色,即数据库里的"用户"或"用户组")来做全部授权。三类角色分工明确:

  • authenticator:登录数据库的角色,权限最小,唯一职责是"变身"成其他角色
  • web_anon:未认证请求的默认身份
  • webuser等:已认证用户对应的角色
CREATE ROLE authenticator LOGIN NOINHERIT NOCREATEDB NOCREATEROLE NOSUPERUSER; CREATE ROLE anonymous NOLOGIN; CREATE ROLE webuser NOLOGIN;

NOLOGIN意味着用户角色不能直接登录,只能被authenticator切换,这是防止旁路的关键。

2.2 每个请求如何匹配到一个数据库角色

客户端带上 JWT(JSON Web Token,一种带签名的身份令牌),JWT 里的role声明指向某个数据库角色。PostgREST 验签通过后,用SET LOCAL ROLE切到该角色再执行查询:

curl "http://localhost:3000/todos" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." # PostgREST 内部执行:SET LOCAL ROLE webuser;
GRANT webuser TO authenticator; GRANT SELECT, INSERT ON api.todos TO webuser;

没带 JWT、或 JWT 里没有role声明,就落到前文提到的db-anon-role。如果某个角色没被GRANTauthenticator,对应请求会直接失败——这是最常见的"权限不通"原因。

2.3 为什么授权全部交给数据库

PostgREST 自己只管"你是谁"(认证),"你能干什么"(授权)完全由数据库的角色和权限决定。这样做的好处是只有一份安全事实来源:你在 psql 里能看到的权限,就是 API 上生效的权限。SECURITY DEFINER函数(以函数属主身份执行的函数)、RLS 策略都直接参与 API 行为,无需在应用层重复实现。

官方教程用电影、影星、影片这几张表演示外键关系,PostgREST 会基于这些外键自动生成嵌入查询能力。

3. 关键配置项:三种来源与热重载

3.1 配置文件与环境变量怎么选

环境变量规则:参数名大写、前缀PGRST_、连字符换成下划线。

# 文件里这样写 db-uri = "postgres://user:pass@host:5432/dbname" server-port = 3000
# 容器里这样写 export PGRST_DB_URI="postgres://user:pass@host:5432/dbname" export PGRST_SERVER_PORT=8080

优先级:环境变量 > 配置文件。Docker 部署用环境变量,裸机部署用配置文件,两者别混着改同一个参数。

3.2 把敏感配置搬进数据库

db-pre-config指向一个数据库函数,可以在库里动态下发配置,密钥不落盘:

CREATE SCHEMA postgrest; GRANT USAGE ON SCHEMA postgrest TO authenticator; CREATE FUNCTION postgrest.pre_config() RETURNS void AS $$ SELECT set_config('pgrst.db_schemas', 'api', true), set_config('pgrst.jwt_secret', 'reallyreallyreallyreallyverysafe', true); $$ LANGUAGE sql;

注意库里参数名用下划线:db_schemas而不是db-schemas。配置文件里只需一行db-pre-config = "postgrest.pre_config"

3.3 修改后如何生效

大多数参数支持热重载,不用重启进程:

# 方式一:发信号 killall -SIGUSR2 postgrest # 方式二:在 psql 里通知 NOTIFY pgrst, 'reload config';

但环境变量不支持重载——容器改了PGRST_*后必须重启,或改用上面的库内配置。

关键参数速查:

参数类型默认值说明
db-uriString必填PostgreSQL 连接串
db-schemasStringpublic暴露成 API 的 schema,逗号分隔
db-anon-roleString匿名请求使用的角色,不设则禁止匿名访问
jwt-secretStringJWT 验签密钥,至少 32 字符
db-poolInt10连接池大小
db-max-rowsInt无限制单次查询最大返回行数
openapi-modeStringfollow-privilegesOpenAPI 文档生成模式
admin-server-portInt管理端口,提供健康检查与指标

4. 生产级加固:RLS、连接池与健康检查

4.1 行级安全:让每个用户只看自己的行

RLS(行级安全,即按行过滤谁能看到哪条数据)是 PostgREST 最省代码的隔离手段。

ALTER TABLE api.todos ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON api.todos USING (owner = current_setting('request.jwt.claims', true)::json->>'sub');

策略里的request.jwt.claims由 PostgREST 注入当前请求的 JWT 声明。不同用户的请求查同一张表,各自只看到自己的行——你不需要在 SQL 视图里手写任何过滤逻辑。

4.2 连接池与慢查询防线

PostgREST 内部维护连接池,生产上建议显式收紧:

db-pool = 20 db-pool-max-lifetime = 3600 db-pool-max-idletime = 30

同时给每个被切换的角色设置语句超时,防止慢查询占死连接:

ALTER ROLE webuser SET statement_timeout = '15s';

4.3 开启管理端口

admin-server-port是独立于 API 的管理端口,提供健康检查和指标:

curl -I http://localhost:3001/live

live只确认进程活着,返回 200 或 500。

curl -I http://localhost:3001/ready

ready额外检查连接池和 schema cache 状态,异常时返回 503,适合挂到负载均衡器的探活上。

5. 常见踩坑与排查

5.1 401 permission denied:查 GRANT 链

按顺序检查三件事:该角色有没有被GRANT ... TO authenticator、角色对 schema 有没有USAGE、对表有没有对应操作权限。写操作还要单独给序列授权:

-- 诊断:看角色实际拥有哪些表权限 SELECT table_name, privilege_type FROM information_schema.role_table_grants WHERE grantee = 'webuser';
-- 修复:补上插入自增列所需权限 GRANT USAGE ON SEQUENCE api.todos_id_seq TO webuser;

POST 报 401 而 SELECT 正常,十有八九是漏了序列权限。

5.2 404 resource not found:查 schema cache

三种常见原因:表不在db-schemas里、表名拼错、对象是启动之后新建的。最后一种执行NOTIFY pgrst;重载即可。

5.3 用管理端点看它"看到了什么"

curl http://localhost:3001/schema_cache

返回 JSON 里按dbTablesdbRoutines等字段列出 PostgREST 当前缓存的对象。你要找的表不在列表里,说明它根本没被识别进来——问题在 schema 配置或权限,而不是缓存时序。

下一步

  • 把匿名角色换成最小只读集,再给写操作角色逐表补GRANT,参考 docs/references/auth.rst 里的角色模型。
  • 给核心表启用 RLS,用不同sub声明的 JWT 各发一次请求,验证行隔离是否按预期生效。
  • 启用openapi端点(默认开启),把它接入网关或前端文档站,让 API 文档跟着数据库结构自动更新。

【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询