PostgREST 从建表到 REST API 上线:4 层实操指南 PostgREST 从建表到 REST API 上线4 层实操指南【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrestPostgREST 把 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:mysecretdb:5432/postgres db: image: postgres ports: - 5432:5432 environment: POSTGRES_DB: postgres POSTGRES_USER: authenticator POSTGRES_PASSWORD: mysecretPGRST_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:mysecretlocalhost:5432/postgres db-schemas api db-anon-role web_anondb-schemas决定哪些 schema 会暴露成接口db-anon-role指定没带身份的请求用哪个角色执行。1.3 验证端点404 时先查 schema cachepostgrest 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 每个请求如何匹配到一个数据库角色客户端带上 JWTJSON 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。如果某个角色没被GRANT给authenticator对应请求会直接失败——这是最常见的权限不通原因。2.3 为什么授权全部交给数据库PostgREST 自己只管你是谁认证你能干什么授权完全由数据库的角色和权限决定。这样做的好处是只有一份安全事实来源你在 psql 里能看到的权限就是 API 上生效的权限。SECURITY DEFINER函数以函数属主身份执行的函数、RLS 策略都直接参与 API 行为无需在应用层重复实现。官方教程用电影、影星、影片这几张表演示外键关系PostgREST 会基于这些外键自动生成嵌入查询能力。3. 关键配置项三种来源与热重载3.1 配置文件与环境变量怎么选环境变量规则参数名大写、前缀PGRST_、连字符换成下划线。# 文件里这样写 db-uri postgres://user:passhost:5432/dbname server-port 3000# 容器里这样写 export PGRST_DB_URIpostgres://user:passhost:5432/dbname export PGRST_SERVER_PORT8080优先级环境变量 配置文件。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-secretString无JWT 验签密钥至少 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/livelive只确认进程活着返回 200 或 500。curl -I http://localhost:3001/readyready额外检查连接池和 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 里按dbTables、dbRoutines等字段列出 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),仅供参考