5分钟把 PostgreSQL 变成 REST API:PostgREST 新手上手指南
【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest
先别急着看安装步骤,直接看效果。假设你的 PostgreSQL 里有一张todos表,对 PostgREST 发一个请求:
curl http://localhost:3000/todos几毫秒后返回:
[{"id":1,"task":"写个查询","done":false}, {"id":2,"task":"部署到服务器","done":true}]完事了。没有 controller,没有 DTO,没有任何一行接口代码——表就是接口。读完这篇文章,你能自己用 Docker 跑起一套 PostgREST 服务,给表配好最小权限,并做出过滤、分页、关联查询。全程大概 10 分钟。
PostgREST 是什么,帮你省了什么
一句话:PostgREST 是一个独立的 Web 服务,把任意 PostgreSQL 数据库暴露成 RESTful API。你平时手写接口层要干的活——路由、解析查询参数、拼 SQL、序列化成 JSON、处理分页头——它全包了,而且性能很好。更关键的是,"谁能看、谁能改"不由框架代码决定,而由 PostgreSQL 的角色和权限决定。加一个端点 = 建一张表,加一个权限策略 = 写一条 GRANT。
Docker 最快启动路径
推荐走 Docker:官方镜像用 Nix 从scratch构建,里面只有一个静态二进制,整包约 14 MB,没有 shell 和多余依赖,攻击面小,拉取也快。不想折腾 compose 的话,也可以直接:
docker run -p 3000:3000 -e PGRST_DB_URI="postgres://authenticator:mysecretpassword@db:5432/postgres" postgrest/postgrest完整一点的 docker-compose 写法(数据库和应用一起起):
services: db: image: postgres environment: POSTGRES_PASSWORD: mysecretpassword ports: - "5432:5432" server: image: postgrest/postgrest environment: PGRST_DB_URI: postgres://authenticator:mysecretpassword@db:5432/postgres PGRST_DB_SCHEMAS: api PGRST_DB_ANON_ROLE: web_anon ports: - "3000:3000" depends_on: - dbdocker compose up -d之后,访问http://localhost:3000能看到 PostgREST 的欢迎页,说明服务已就绪。
其他安装方式带过一句:各平台基本都有包管理器渠道(brew install postgrest、pacman -S postgrest等),也可以从官方 release 下载静态二进制直接跑。注意二进制需要系统装有 libpq(PostgreSQL 的 C 客户端库),Docker 镜像则不需要操心这些。
从零跑通第一个 PostgreSQL REST API
建一张表
先给 API 专用的表建一个独立的 schema(相当于表所在的"命名空间"),避免把内部表也暴露出去:
create schema api; create table api.todos ( id int primary key generated by default as identity, task text not null, done boolean not null default false ); insert into api.todos (task) values ('买咖啡'), ('写周报');配最小权限(只读)
表建好了,谁有资格读?给匿名访客单独开一个只读角色:
create role web_anon nologin; grant usage on schema api to web_anon; grant select on api.todos to web_anon;再建一个认证器角色:它持有db-uri里的密码,负责和数据库建立连接,然后"变身"成别的角色去执行查询:
create role authenticator noinherit login password 'mysecretpassword'; grant web_anon to authenticator;grant web_anon to authenticator是关键:它允许连接切换成web_anon。少了这一句,所有请求都会报权限错误。
最小配置与启动
建一个postgrest.conf,跑通只需要三行:
db-uri = "postgres://authenticator:mysecretpassword@localhost:5432/postgres" db-schemas = "api" db-anon-role = "web_anon"db-uri:PostgREST 连数据库用的连接串(认证器角色的密码在里面)。db-schemas:哪些 schema 里的表/视图会暴露成端点。db-anon-role:没带 JWT 的请求以哪个角色执行。
启动并验证:
postgrest postgrest.conf curl http://localhost:3000/todos看到刚才插入的两行数据,恭喜,你的表已经是个 API 了。顺手做个写操作试试:
curl -X POST http://localhost:3000/todos -H "Content-Type: application/json" -d '{"task":"再写一个"}'会得到 401 和"message": "permission denied for table todos"——这不是 bug,是我们只授了 SELECT,权限模型按预期生效。
权限怎么控:谁能看,谁能改
PostgREST 自己不管授权,它只负责把请求"翻译"成数据库操作,判断全交给 PostgreSQL 的角色系统。
理解三个角色就够了:
- 认证器(authenticator):拿着
db-uri密码建连接的角色,本身不给任何表权限。 - 匿名角色(anon role):没带令牌的请求走它,一般只读,甚至只读几张公开表。
- 用户角色:登录后对应多个角色,各配各的权限。
登录怎么关联?请求头带一个 JWT,PostgREST 用jwt-secret验签后,读取载荷里的role声明,把连接切换成同名数据库角色:
create role web_user nologin; grant select, insert, update on api.todos to web_user; grant web_user to authenticator;curl http://localhost:3000/todos -H "Authorization: Bearer <your-jwt>"于是权限变成:匿名只能查;带{"role":"web_user"}令牌的请求可以增改;没给 GRANT 的东西,谁都动不了。加角色、改权限都是普通 SQL,不用重启服务。
查询参数速查
PostgREST 的查询能力全在 URL 参数里,不用写任何代码:
| 场景 | 参数示例 | 说明 |
|---|---|---|
| 过滤 | /todos?done=is.false | 常用操作符:eq.neq.gt.lt.like.in.(a,b,c)is.null |
| 组合逻辑 | /todos?or=(done.is.true,task.like.%周报%) | or=里写多个条件 |
| 排序 | /todos?order=created_at.desc | 多列用逗号分隔 |
| 分页 | /todos?limit=10&offset=10 | 响应头自带Content-Range,方便算总页数 |
| 只取部分列 | /todos?select=id,task | 减少传输体积 |
| 关联嵌入 | /films?select=id,title,actors(*) | 沿外键把关联表"嵌"进结果 |
| 聚合 | /todos?select=count | 或select=count(...)统计 |
关联嵌入是它最好用的功能之一:只要表之间有外键,select里用括号把子资源展开,一次请求拿到树形结构:
上生产前:配置与部署要点
常用配置项就这些,其余详见仓库里的 配置文档:
| 配置项 | 说明 |
|---|---|
db-uri/db-pool | 连接串与连接池大小(默认 10) |
db-anon-role | 匿名请求使用的角色 |
db-schemas | 对外暴露的 schema 列表 |
jwt-secret | 至少 32 字符;对称签名密钥。配置 PostgREST 的 jwt-secret 时别图省事用短字符串 |
server-port | HTTP 端口,默认 3000 |
db-max-rows | 单次查询最大返回行数,防止全表拖垮 |
server-cors-allowed-origins | 前端跨域白名单 |
两个实用机制:
- 环境变量覆盖:任何配置项都可以用
PGRST_前缀的环境变量覆盖,比如PGRST_JWT_SECRET、PGRST_SERVER_PORT。K8s、Docker 场景下用环境变量比挂载配置文件干净得多。 - 热重载:修改配置后向进程发
SIGUSR2即可重载,不用重启断流。
Docker 部署要点:镜像无 shell,排查问题别指望docker exec进去ls;生产建议只映射 3000 端口、数据库不暴露公网,把 PostgREST 放在反代(Nginx 等)后面处理 TLS。
新手高频坑
1. 报错libpq.so加载失败—— 你装的是裸二进制,系统缺 PostgreSQL 客户端库。装上它即可(Debian/Ubuntu 是libpq-dev),或者干脆换 Docker 跑,绕开这个问题。
2. 启动就连不上数据库—— 三个方向:密码对不对;角色有没有LOGIN权限(认证器必须能登录);服务器pg_hba.conf是否放行了该来源和认证方式。Docker 里注意db-uri的主机名要写服务名而不是localhost。
3. 请求返回 401/403,permission denied—— 十有八九是 GRANT 没配齐。按顺序查:角色授给了认证器吗?schema 的USAGE授了吗?表的读/写权限授给了执行角色吗?
4. 端口被占用—— 5432 被本机 PostgreSQL 占着时,把 compose 里映射的第一个端口改掉(如5433:5432),记得同步改db-uri;PostgREST 默认占 3000,冲突就改server-port。
下一步
到这里你已经拥有:一张表、一个只读 API、一套基于数据库角色的权限控制——而这一切的"源代码"就是 SQL。接下来推荐两条线:想收紧到行级别?学RLS(行级安全),让每个用户只看见自己的数据;想要文档?打开/openapi看看自动生成的 OpenAPI 规范。更深入的内容可以看仓库里的 官方教程。
【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考