PostgREST 入门教程:从零构建基于 PostgreSQL 的 REST API
PostgREST 入门教程从零构建基于 PostgreSQL 的 REST API【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest本教程对应仓库文档 Tutorial 0 - Get it Running带领你从零启动 PostgREST把一个 PostgreSQL 数据库变成可用的 RESTful API。读完本文你将掌握用 Docker 快速拉起 PostgreSQL、安装 PostgREST 的多种方式、设计数据库对象schema / 表 / 角色驱动 API 端点与权限的完整思路以及用curl验证只读 API 的实战技能。PostgREST 是什么数据库即 APIPostgREST 是一个独立的 Web 服务器它把 PostgreSQL 数据库直接转化为 RESTful API。关键在于API 完全由底层数据库结构定制——不需要编写任何业务代码端点、权限全部来自数据库对象表、视图、角色、函数。你只需要建数据库API 就自动长出来了。从源码结构看这个仓库是 PostgREST 的完整 Haskell 实现src/library/PostgREST/ 下按AuthJWT 认证、Config配置解析、Plan请求计划、QuerySQL 生成等模块组织印证了数据库驱动 API的设计PostgREST 读取数据库 schema 元数据把 HTTP 请求翻译成 SQL 语句执行。通过本教程你将得到一个可运行的数据库、一个 PostgREST 服务器、以及一个简单的单用户 todo 列表 API。Step 1. 安装 PostgreSQL如果你已经熟悉 PostgreSQL 并在系统上安装过可以直接使用现有实例最低版本要求见 安装说明。本教程推荐用 Docker 运行数据库因为本地配置数据库对新手而言过于复杂。如果你的机器还没有 Docker请先安装 Docker 并确保 Docker 服务已启动。然后拉取并启动数据库镜像sudo docker run --name tutorial -p 5432:5432 \ -e POSTGRES_PASSWORDnotused \ -d postgres这条命令以守护进程方式运行容器并把容器内的 5432 端口映射到宿主机使它对系统其他部分而言就像一个普通的 PostgreSQL 服务器。注意只有当你的计算机默认端口上没有其他 PostgreSQL 实例运行时这条命令才能成功。如果端口被占用你会看到类似这样的错误docker: Error response from daemon: [...]: Bind for 0.0.0.0:5432 failed: port is already allocated.此时需要把两个 5432 中的第一个改成其他端口例如5433:5432。记得在第 4 步的配置文件中同步调整端口Step 2. 安装 PostgRESTPostgREST 有两种主流安装方式使用系统包管理器或下载预编译二进制。方式一使用包管理器PostgREST 已进入多个主流平台的软件源完整的平台清单见 安装共享文档常见命令如下平台命令macOSHomebrewbrew install postgrestFreeBSDportspkg install hs-postgrestArch Linuxpacman -S postgrestNixnixpkgsnix-env -i postgrestWindowsChocolatey / Scoopchoco install postgrest或scoop install postgrest安装完成后先试试运行postgrest -h如果一切正常它会打印帮助页面包含版本号和可用选项。方式二下载预编译二进制PostgREST 以单个二进制文件分发针对 macOS、Windows、Linux、FreeBSD 的主流发行版都有编译版本。如果你的平台不在预编译清单中可以参照 构建指南 自行从源码构建。预编译二进制是.tar.xz压缩文件Windows 是 zip 文件解压# 从发布页面下载 postgrest-version-platform.tar.xz tar xJf postgrest-version-platform.tar.xz解压后得到一个名为postgrest的文件Windows 下是postgrest.exe。验证一下./postgrest -h正常会打印版本号和可用选项。你可以继续在下载目录运行这个二进制也可以把它复制到系统目录如 Linux 的/usr/local/bin以便从任意目录直接执行postgrest。注意PostgREST 依赖 PostgreSQL 的 C 客户端库 libpq。缺少该库时会报错 error while loading shared libraries: libpq.so.5。各平台修复方式Ubuntu / Debiansudo apt-get install libpq-devFedora / CentOS / Red Hatsudo yum install postgresql-libsmacOSbrew install postgresqlWindowsPostgreSQL 安装目录的 BIN 文件夹如C:\Program Files\PostgreSQL\10\bin包含所有所需 DLL将该目录加入 PATH 即可可在管理员命令行执行setx /m PATH %PATH%;C:\Program Files\PostgreSQL\10\binStep 3. 为 API 创建数据库先进入容器内的 SQL 控制台psqlsudo docker exec -it tutorial psql -U postgres你会看到 psql 提示符psql (16.2) Type help for help. postgres#3.1 创建 API schema首先要为将要暴露在 API 中的数据库对象创建一个命名 schema名称可以任意取这里使用 apicreate schema api;3.2 创建 todos 表我们的 API 将有一个端点/todos它来自一张表create table api.todos ( id int primary key generated by default as identity, done boolean not null default false, task text not null, due timestamptz ); insert into api.todos (task) values (finish tutorial 0), (pat self on back);这里用到了两个值得注意的建模技巧id int primary key generated by default as identityPostgreSQL 10 的 identity 列比serial更符合 SQL 标准due timestamptz允许为空的带时区时间戳表示待办事项的截止时间。3.3 创建匿名角色 web_anon接下来创建一个用于匿名 Web 请求的角色。当请求到达时PostgREST 会在数据库中切换到该角色来执行查询create role web_anon nologin; grant usage on schema api to web_anon; grant select on api.todos to web_anon;web_anon角色有权限访问apischema并读取todos表中的行。注意这里只授予了select——这正是后面匿名用户只能读不能写的原因。3.4 创建连接角色 authenticator好的实践是为连接数据库创建一个专门的角色而不是使用权限极高的postgres角色。我们把这个角色命名为authenticator并授予它切换到web_anon角色的能力create role authenticator noinherit login password mysecretpassword; grant web_anon to authenticator;退出 psql准备启动 API\q角色模型的要点authenticator带login用于建立数据库连接与web_anon带nologin用于执行匿名请求的 SQL是两个不同角色。PostgREST 启动后用authenticator连接数据库收到 HTTP 请求后通过SET ROLE切换到 JWT 指定的角色匿名时是db-anon-role再执行 SQL。这种连接角色 执行角色的分离是 PostgREST 安全模型的基石细节可参考 数据库授权机制说明。Step 4. 配置并运行 PostgRESTPostgREST 通过配置文件告知数据库连接方式。创建文件tutorial.conf内容如下db-uri postgres://authenticator:mysecretpasswordlocalhost:5432/postgres db-schemas api db-anon-role web_anon三个核心参数的含义参数作用db-uri标准 PostgreSQL 连接字符串PostgREST 用其中的用户即authenticator角色连接数据库db-schemas暴露给客户端的数据库 schema 列表apischema 中的对象将成为 API 端点db-anon-role处理匿名请求时切换到的数据库角色即刚才创建的web_anon如果没用 Docker请确认端口号正确并把postgres替换为你添加 todos 表所在的数据库名。注意如果你在第 1 步改过端口如5433:5432这里也要同步修改配置文件远不止这三个参数完整清单参见 配置参考。例如 server-port 控制 HTTP 监听端口默认 3000、jwt-secret用于 JWT 认证、server-host控制绑定地址。你还可以运行postgrest --example查看所有可用的配置参数示例。现在启动服务器# 通过包管理器安装的 postgrest postgrest tutorial.conf # 或直接运行二进制 ./postgrest tutorial.conf你会看到类似输出Starting PostgREST 12.0.2... Successfully connected to PostgreSQL 14.10 (Ubuntu 14.10-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit API server listening on port 3000服务器已就绪可以开始服务 Web 请求了。Step 5. 验证你的第一个 APIAPI 探索工具有很多本教程使用大概率已预装的curl。打开一个新终端保持运行 PostgREST 的终端不关闭请求 todoscurl http://localhost:3000/todosAPI 返回[ { id: 1, done: false, task: finish tutorial 0, due: null }, { id: 2, done: false, task: pat self on back, due: null } ]这就是数据库即 API最直观的体现你只建了一张表、授予了一个角色读权限PostgREST 便自动生成了GET /todos端点并按id、done、task、due列返回 JSON。由于当前角色权限下匿名请求对todos表是只读的尝试新增一条 todo 会失败curl http://localhost:3000/todos -X POST \ -H Content-Type: application/json \ -d {task: do bad thing}返回 401 Unauthorized{ code: 42501, details: null, hint: null, message: permission denied for table todos }错误码42501是 PostgreSQL 的insufficient_privilege错误透传自数据库——这正是 PostgREST 权限模型的精髓HTTP 层的授权完全委托给数据库的行级/表级权限服务端不额外维护权限逻辑。任何端点、任何方法的可用性都由数据库角色权限决定这也让安全审计可以完全在数据库层面进行。从源码看 PostgREST 的运行机制为了更深入理解为什么建表 授权就能得到 API可以从仓库源码找到对应实现配置解析三个关键参数如何生效Config.hs 中的AppConfig记录类型定义了全部配置项。其中与本文直接相关的configDbUri数据库连接字符串最终被解析为 Hasql 连接设置configDbSchemas暴露的 schema 列表决定 schema 缓存SchemaCache加载哪些数据库对象configDbAnonRole匿名角色对应 Auth.hs 中认证结果的兜底角色。认证与角色切换从 Auth.hs 的getAuthResult可以看到认证流程读取配置 → 获取当前时间 → 解析并校验 JWTAuth/Jwt.hs 的parseAndDecodeClaims→ 得出AuthResult。其中 Jwt.hs 的parseClaims明确了角色提取逻辑若 JWT 未携带role声明则回退到db-anon-role——这正是教程里web_anon生效的底层原因。匿名只读的验证仓库的测试套件也覆盖了这一场景测试配置 test/spec/Feature/Auth/AuthSpec.hs 中对匿名/空 JWT 请求的断言以及 fixtures/roles.sql 中web_anon、authenticator等角色的定义与教程中的角色模型完全一致。这说明本文的做法就是 PostgREST 官方测试所验证的标准用法。下一步从只读到可写现在你已经有一个基于数据库的基础 API 了。在后续教程 Tutorial 1 - The Golden Key 中将在此基础上扩展添加可信用户角色创建todo_user角色并授予写权限grant all on api.todos to todo_user配置 JWT 密钥在tutorial.conf中加入jwt-secret至少 32 字符客户端用签名的 JSON Web Token 认证签发令牌并请求写操作用Authorization: Bearer token请求头配合POST/PATCH增改数据令牌过期与即时撤销利用exp声明控制有效期或通过db-pre-request指定认证钩子函数实现即时撤销。JWT 的校验细节exp、nbf、iat、aud等声明的检查逻辑在 Auth/Jwt.hs 的checkForErrors中实现测试见 AuthSpec.hs。常见问题排查现象原因与解决Bind for 0.0.0.0:5432 failed: port is already allocated宿主机 5432 端口被占用改用5433:5432映射并同步修改db-uri端口error while loading shared libraries: libpq.so.5缺少 libpq按第 2 步的提示安装对应系统包permission denied for table todos角色没有对应表的权限回到第 3 步检查grant语句启动后无法访问 API确认db-schemas拼写正确、db-anon-role已设置未设置时匿名访问会被拒绝可运行postgrest --example对照配置修改配置后不生效重启 PostgREST进阶场景可用SIGUSR2信号或数据库NOTIFY热加载配置见 配置参考 的重载章节至此你已经亲手完成了一个数据库驱动的 REST API只写了十几行 SQL 和 3 行配置文件就拥有了标准 JSON 输出、自动生成的端点以及数据库强制的权限控制。后续教程将进一步展示更复杂的用户访问控制和更丰富的表与查询场景。【免费下载链接】postgrestREST API for any Postgres database项目地址: https://gitcode.com/GitHub_Trending/po/postgrest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考