PostgREST 入门篇

PostgREST 是一个为 PostgreSQL 数据库提供 REST API 的后端服务, 是用 Haskell 开发的开源软件,源代码非常值得学习。有了 PostgREST,搭配 PostgreSQL,只要建好表,加上一个简单的配置,就可以拥有一个 REST API 后端,简直不要太爽。

  • 官方文档:https://docs.postgrest.org/en/v12/index.html
  • GitHub:https://github.com/PostgREST/postgrest

安装

PostgREST 的安装十分简单,只需要在 GitHub 的 release 页面下载对应的可执行文件就行,下载过来是压缩包,解压之后会得到一个可执行文件。

虽然 PostgREST 是以单个二进制文件形式发布的,但是它需要依赖 PostgreSQL 的库,所以最好还是先安装一下 PostgreSQL,然后将 bin 目录(PostgreSQL\13\bin)添加到 path 环境变量。

最后我们在命令行中运行 postgrest -v 看到输出版本号,就说明 OK 了。

>postgrest -v
PostgREST 12.2.8 (4a3936f)

如果缺少 PostgreSQL 库,运行 postgrest 命令不会有任何输出,也没有报错,我这个版本是这样。

准备数据

现在让我们在数据库中准备一些数据用于测试。打开 psql ,登录到你的数据库,这里要用 root 账号去登录。

第一步是创建 scheme 和表。如果把表比作文件的话,那么 scheme 就相当于文件夹。虽然创建 schema 并不是一定必须的,但是它有利于我们的公私数据隔离和权限管控。如果不创建 schema,那么所有表都会在默认的 public schema 下。

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,
  due timestamptz
);

insert into api.todos (task) values
  ('finish tutorial 0'), ('pat self on back');

我们创建了一个交 api 的 schema,并在它下面创建了一个 todos 表,并插入了两条数据。

然后我们要创建两个角色。第一个角色我们称为“陌生人”角色,是给未登录的用户来查询数据的。注意这里的“登录”不是指登录数据库,而是登录你的网站。PostgREST 是使用 JWT 来验证权限的,所有不带 jwt token 的请求都会切换到这个“陌生人”角色去查数据库,那么它能看到什么数据,就完全取决于这个“陌生人”角色所具有的权限,一般是只给一些公开表的只读权限。

create role web_anon nologin;

grant usage on schema api to web_anon;
grant select on api.todos to web_anon;

这里我们创建了一个叫 web_anon 的角色,然后授予它使用 api schema 和查询 todos 表的权限。

接下来还要创建一个用来连接数据库的角色,它才是给 PostgREST 用来登录数据的。

create role authenticator noinherit login password 'mysecretpassword';
grant web_anon to authenticator;

这里我们创建了一个叫 authenticator 的角色用来连接数据库,注意它一定要给 login 的权限。然后我们授予它 web_anon 的权限,这样当未登录的用户发来请求时,PostgREST 才能从 authenticator 角色切换到 web_anon 来执行 SQL。PostgREST 的权限管理正是通过不同的 PostgreSQL 角色来实现的。当然如果你选择直接用超级用户连接数据库的话,这一步就可以省了,不过不建议生产环境这么玩。

配置

程序、数据都准备好了,要启动服务我们还需要一个配置文件。我们创建一个叫 toturial.conf 的文件,然后输入以下内容。

db-uri = "postgres://authenticator:mysecretpassword@localhost/postgres"
db-schema = "api"
db-anon-role = "web_anon"

这就是最简单的配置了,只需要指定数据库连接地址,schema 和“陌生人”角色就可以了。如果是比较老的 PostgreSQL,可能不支持这种 url 形式,而是键值对。

见证奇迹

最后一步,在命令行运行:

> postgrest toturial.conf
14/Mar/2025:10:29:26 +0800: Starting PostgREST 12.2.8 (4a3936f)...
14/Mar/2025:10:29:26 +0800: Listening on port 3000
14/Mar/2025:10:29:26 +0800: Successfully connected to PostgreSQL 13.20, compiled by Visual C++ build 1942, 64-bit
14/Mar/2025:10:29:26 +0800: Config reloaded
14/Mar/2025:10:29:26 +0800: Listening for notifications on the "pgrst" channel
14/Mar/2025:10:29:26 +0800: Schema cache queried in 0.0 milliseconds
14/Mar/2025:10:29:26 +0800: Schema cache loaded 1 Relations, 0 Relationships, 0 Functions, 0 Domain Representations, 4 Media Type Handlers, 597 Timezones
14/Mar/2025:10:29:26 +0800: Schema cache loaded in 0.0 milliseconds

如果一切正常,你会看到服务在 3000 端口启动,访问 http://localhost:3000/todos 就能看到我们之前准备的数据了,是一个 json 列表。

在命令行输入 postgrest -e 可以会打印出一份完整的配置, -e--example 的简短形式。

>postgrest -e
## Admin server used for checks. It's disabled by default unless a port is specified.
# admin-server-port = 3001

## The database role to use when no client authentication is provided
# db-anon-role = "anon"

## Notification channel for reloading the schema cache
db-channel = "pgrst"

## Enable or disable the notification channel
db-channel-enabled = true

## Enable in-database configuration
db-config = true

## Function for in-database configuration
## db-pre-config = "postgrest.pre_config"

## Extra schemas to add to the search_path of every request
db-extra-search-path = "public"

## Limit rows in response
# db-max-rows = 1000

## Allow getting the EXPLAIN plan through the `Accept: application/vnd.pgrst.plan` header
# db-plan-enabled = false

## Number of open connections in the pool
db-pool = 10

## Time in seconds to wait to acquire a slot from the connection pool
# db-pool-acquisition-timeout = 10

## Time in seconds after which to recycle pool connections
# db-pool-max-lifetime = 1800

## Time in seconds after which to recycle unused pool connections
# db-pool-max-idletime = 30

## Allow automatic database connection retrying
# db-pool-automatic-recovery = true

## Stored proc to exec immediately after auth
# db-pre-request = "stored_proc_name"

## Enable or disable prepared statements. disabling is only necessary when behind a connection pooler.
## When disabled, statements will be parametrized but won't be prepared.
db-prepared-statements = true

## The name of which database schema to expose to REST clients
db-schemas = "public"

## How to terminate database transactions
## Possible values are:
## commit (default)
##   Transaction is always committed, this can not be overriden
## commit-allow-override
##   Transaction is committed, but can be overriden with Prefer tx=rollback header
## rollback
##   Transaction is always rolled back, this can not be overriden
## rollback-allow-override
##   Transaction is rolled back, but can be overriden with Prefer tx=commit header
db-tx-end = "commit"

## The standard connection URI format, documented at
## https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
db-uri = "postgresql://"

# jwt-aud = "your_audience_claim"

## Jspath to the role claim key
jwt-role-claim-key = ".role"

## Choose a secret, JSON Web Key (or set) to enable JWT auth
## (use "@filename" to load from separate file)
# jwt-secret = "secret_with_at_least_32_characters"
jwt-secret-is-base64 = false

## Enables and set JWT Cache max lifetime, disables caching with 0
# jwt-cache-max-lifetime = 0

## Logging level, the admitted values are: crit, error, warn, info and debug.
log-level = "error"

## Determine if the OpenAPI output should follow or ignore role privileges or be disabled entirely.
## Admitted values: follow-privileges, ignore-privileges, disabled
openapi-mode = "follow-privileges"

## Base url for the OpenAPI output
openapi-server-proxy-uri = ""

## Configurable CORS origins
# server-cors-allowed-origins = ""

server-host = "!4"
server-port = 3000

## Allow getting the request-response timing information through the `Server-Timing` header
server-timing-enabled = false

## Unix socket location
## if specified it takes precedence over server-port
# server-unix-socket = "/tmp/pgrst.sock"

## Unix socket file mode
## When none is provided, 660 is applied by default
# server-unix-socket-mode = "660"

有些配置我们会在后面遇到的时候再详细解释,但是大部分应该能一眼猜出大概意思。比如 server-port = 3000 可以用来设置服务的端口,默认是 3000 端口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值