PostgREST 从零到一:安装部署配置,跑通你的第一个 PostgreSQL REST API
【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest
这篇文章带你把 PostgREST 装好、连上 PostgreSQL,配置完成后跑通第一个 REST API。PostgREST 是一个独立 Web 服务器:它读取数据库里的表、视图和函数,把它们直接变成 REST 端点,权限判定全部交给 PostgreSQL 的角色系统。按下面的顺序做,大概二十分钟能跑通。
前提检查:确认 PostgreSQL 实例就绪
这一步解决"PostgREST 有没有一个能连上的数据库"的问题。PostgREST 自身不存数据,它只是把数据库包装成 API,所以前提只有一个:一个可远程(或本地)连接的 PostgreSQL 实例。
# 用 psql 验证端口与账号能连通 psql -h localhost -p 5432 -U postgres -c 'select version();'本机没有 PostgreSQL 的话,直接拉一个容器最省事:
docker run -d --name todo_pg -p 5432:5432 \ -e POSTGRES_PASSWORD=notused postgres确认能连上、知道一个可用的登录账号和密码,就可以进入下一步。
选安装路线:开发机、单机还是容器
这一步解决"postgrest 二进制从哪来"。三条路线按场景选,别纠结:
| 场景 | 路线 | 安装命令 | 验证命令 |
|---|---|---|---|
| 开发机日常开发 | 包管理器 | brew install postgrest(macOS)或pacman -S postgrest(Arch) | postgrest --help |
| 需要指定版本、不想装依赖 | 预编译二进制 | 从项目 Release 页下载对应平台的 tar 包后tar xJf postgrest-<version>-<platform>.tar.xz | ./postgrest --help |
| 生产容器化部署 | Docker 官方镜像 | docker run -p 3000:3000 -e PGRST_DB_URI="postgres://authenticator:pwd@host:5432/todo" postgrest/postgrest | curl -s localhost:3000/ |
几点补充:
- Windows 上包管理器路线可用
scoop install postgrest或 Chocolatey;Scoop/Chocolatey 之外就是二进制路线,把 PostgreSQL 安装目录的bin加入 PATH 即可。 - 二进制路线要求系统里有 libpq。启动时报
error while loading shared libraries: libpq.so.5时,Ubuntu/Debian 执行sudo apt-get install libpq-dev,RHEL 系执行sudo yum install postgresql-libs。 - Docker 路线的环境变量就是配置(见下一节讲配置),容器只带必要文件,资源占用很小,适合生产。
三条路线装完后,postgrest --help能打出版本号和使用说明就算成功。
数据库侧准备:给三种角色分权限
这一步解决"请求进来后,PostgREST 以什么身份查数据"。核心是三个角色:
- authenticator:唯一的登录角色,只负责建立连接,本身没有任何业务权限;
- 匿名角色(如 anon):不带 JWT 的请求以它执行;
- 用户角色(如 webuser):JWT 里声明对应用户时切换过去执行。
切换机制就是SET LOCAL ROLE,所以必须允许 authenticator 变成其他角色。请求链路如下:
完整 SQL(在目标库执行):
create schema api; -- 唯一可登录角色,最小权限 create role authenticator login noinherit nocreatedb nocreaterole nosuperuser password 'yourpassword'; -- 匿名与用户角色都设 NOLOGIN,只供 SET ROLE 切换 create role anon nologin; create role webuser nologin; grant anon to authenticator; -- 允许切换到这两个角色 grant webuser to authenticator; grant usage on schema api to anon, webuser; create table api.todos ( id int primary key generated by default as identity, title text not null, done boolean not null default false ); -- 最小权限原则:匿名只读,用户全量 grant select on api.todos to anon; grant select, insert, update, delete on api.todos to webuser;如果 API 要暴露多个模式,db-schemas里列出来的每个模式都要单独GRANT USAGE。一个参考的库结构长这样(官方文档里的 film 示例库,表与外键关系):
两个可选加固:
-- 函数默认不再对 PUBLIC 开放,改为逐个 GRANT EXECUTE alter default privileges revoke execute on functions from public; -- 行级安全:每行数据只对"归属该用户"的 JWT 可见 alter table api.todos enable row level security; create policy todo_owner on api.todos using (owner = current_setting('request.jwt.claims', true)::json->>'sub');RLS 的意义在于:表权限只管"能不能碰这张表",行级策略再管"能碰哪些行",两者叠加就是完整的访问控制,不需要写任何服务端代码。更多授权细节可以看仓库里的 docs/explanations/db_authz.rst。
配置 PostgREST 并启动:四个关键参数加环境变量覆盖
这一步解决"进程怎么知道连哪个库、听哪个端口"。写一个postgrest.conf:
# postgrest.conf —— 每个参数名都对应一个 PGRST_ 前缀的环境变量 db-uri = "postgres://authenticator:yourpassword@localhost:5432/todo" db-anon-role = "anon" db-schemas = "api" jwt-secret = "reallyreallyreallyreallyverysafe" server-port = 3000| 参数 | 默认值 | 说明 |
|---|---|---|
db-uri | 无 | 连接串,其中的账号即 authenticator |
db-anon-role | 无 | 不设置则拒绝所有匿名请求 |
db-schemas | public | 暴露成端点的模式列表 |
jwt-secret | 无 | 验证签名用的密钥,至少 32 字符;不设置则拒绝一切认证请求 |
server-port | 3000 | HTTP 监听端口 |
三种配置来源优先级从低到高:配置文件 < 环境变量 < 数据库内配置。环境变量规则是把参数名大写、加下划线、加PGRST_前缀,db-uri对应PGRST_DB_URI——Docker 部署基本全靠它。还嫌麻烦的话,可以用db-pre-config指向一个set_config函数做数据库内配置,全量参数清单见 docs/references/configuration.rst。
启动与成功信号:
postgrest postgrest.conf # 或 postgrest -h 查看帮助,postgrest --example 打印全部参数示例判断启动成功的标准有两个:进程稳定驻留不退出;curl -s http://localhost:3000/返回 200 和一份 OpenAPI JSON(根路径默认输出接口文档)。改完配置不用重启:killall -SIGUSR2 postgrest或在库里执行NOTIFY pgrst, 'reload config';即可热加载(注意 Docker 里环境变量改不了,得用数据库内配置或重建容器)。
第一个 API:一张表跑通 CRUD 全链路
这一步解决"表怎么变成端点、curl 怎么发"。映射规则很直白:db-schemas里的每个表/视图名就是一个路径,api.todos对应GET /todos。
# 查全部,响应头带 Content-Range: 0-2/2,即第 0-2 行/共 2 行 curl -si "http://localhost:3000/todos" # 字段选择 + 过滤 + 排序 + 分页,全部走查询参数 curl -s "http://localhost:3000/todos?select=id,title&done=is.false&order=id.desc&limit=5&offset=0" # 新增(Accept 指定 object+json,返回单对象而非数组) curl -s -X POST "http://localhost:3000/todos" \ -H "Content-Type: application/json" -H "Accept: application/vnd.pgrst.object+json" \ -d '{"title": "跑通第一个 API"}' # 返回 201 和创建的那一行 # 更新 / 删除 curl -s -X PATCH "http://localhost:3000/todos?id=eq.1" -H "Content-Type: application/json" -d '{"done": true}' curl -s -X DELETE "http://localhost:3000/todos?id=eq.1"注意匿名请求此时只有anon的权限:POST/PATCH/DELETE会返回 403,这是正常的权限演示,不是故障。
要用webuser写数据,就带 JWT 请求。生成一个 claims 含{"role": "webuser", "sub": "u1"}的令牌(默认从$.role位置取角色名;拿在线 JWT 工具填一下声明再签名即可):
# 令牌换成自己的,注意 Bearer 前缀 curl -s -X POST "http://localhost:3000/todos" \ -H "Authorization: Bearer <你的JWT>" \ -H "Content-Type: application/json" \ -d '{"title": "带身份写入"}' # 返回 201 —— 这次走的是 webuser 角色跑通 CRUD 后,还有两块能力可以顺手试:外键关联表可以用select=id,title,categories(name)内嵌查询;聚合函数(select=count(*))需要把db-aggregates-enabled设为true才放行。
排错速查:高频问题按症状定位
这一步解决"跑不通时先查哪里"。
| 症状 | 常见原因 | 处理 |
|---|---|---|
| 启动即退出/连接失败 | db-uri的 host、端口、密码错,或pg_hba.conf拒绝该账号 | 先单独用psql以同一账号连通 |
| 401 Unauthorized | 密钥不一致;exp过期;角色声明位置不对 | 核对jwt-secret与签名方一致;时间校验有 30 秒容差;非标准声明位置用jwt-role-claim-key指定 |
| 403 Forbidden | 角色没被GRANT表权限,或缺少GRANT <role> TO authenticator | 先确认切换链完整,再补表级授权 |
| 404 Not Found | 端点所在模式不在db-schemas,或建表后 schema cache 没刷新 | 执行NOTIFY pgrst, 'reload schema'; |
两条调试 SQL 很有用:
-- 确认当前会话是谁(排查角色切换问题) select current_role, current_user; -- 确认某角色实际拿到了哪些表权限(排查 403) select privilege_type, table_name from information_schema.role_table_grants where grantee = 'webuser';另外把log-level = "info"打开后,PostgREST 会把每个 4xx 请求记进日志,配合log-query = true还能看到对应的 SQL。
收尾:你现在能做什么
到这里,你已经拥有一个由 PostgREST 服务的 PostgreSQL REST API:新增一张表或视图、NOTIFY pgrst, 'reload schema'刷新,端点自动出现,权限继续用角色和 RLS 管。下一步建议:给真实应用接入外部认证服务签发的 JWT、按 docs/tutorials/tut0.rst 的思路设计带外键的多表 API,以及在生产上把连接池参数(db-pool默认 10)按并发调一调。
【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考