初识 PostgREST 学习笔记
Andy 2021-03-08
PostgreSQL
Docker
RESTful
# 通过 docker 运行 PostgreSQL
# 创建持久化存储数据卷
docker volume create pgdata
# 拉取镜像并运行容器
sudo docker run --name tutorial -p 5433:5432 \ # 指定容器名称为 tutorial,内部端口5432映射到外部5433
-e POSTGRES_PASSWORD=mysecretpassword \ # -e 通过环境变量设置 POSTGRES_PASSWORD
-v pgdata:/var/lib/postgresql/data # -v 表示数据卷映射
-d postgres # -d 表示后台运行该容器,使用镜像 postgres
# 定义数据库 schema 和 table
# 运行命令并进入容器 docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
# -it 表示 STDIN 打开并分配一个伪终端,tutorial 是容器名称,psql 是执行的命令名称,-U postgres 是传递给该命令的参数
sudo docker exec -it tutorial psql -U postgres
```
psql (9.6.3)
Type "help" for help.
postgres=#
```
# 创建 schema
create schema api;
# 创建 table
create table api.todos (
id serial primary key,
done boolean not null default false,
task text not null,
due timestamptz
);
# 向 todo table 中插入两条数据
insert into api.todos (task) values
('finish tutorial 0'), ('pat self on back');
# 创建一个无需登录的 role(user) web_anon
create role web_anon nologin;
# The web_anon role has permission to access things in the api schema, and to read rows in the todos table.
# 设置角色 web_anon 对 api.todos 的只读权限
grant usage on schema api to web_anon;
grant select on api.todos to web_anon;
```
# 最好是创建一个专供 PostgREST 使用的 Role 同时把 web_anon 加入其中
create role authenticator noinherit login password 'mysecretpassword';
grant web_anon to authenticator;
```
# 退出 postgres 命令行
\q
# 下载并解压 PostgREST
# download from https://github.com/PostgREST/postgrest/releases/latest
tar xJf postgrest-<version>-<platform>.tar.xz
# 运行 PostgREST
# tutorial.conf 配置文件示例
db-uri = "postgres://authenticator:mysecretpassword@localhost:5433/postgres"
db-schema = "api" # 此处设置指明了该 schema (api)中的 table_name 将作为 restful 的资源名称
# 比如该 schema 中 todos 这个 table, 请求URL将为 http://localhost:3000/todos
db-anon-role = "web_anon"
```
# 通过配置文件运行 postgrest
./postgrest tutorial.conf
Listening on port 3000
Attempting to connect to the database...
Connection successful
# 发送 web 请求
GET http://localhost:3000/todos
curl http://localhost:3000/todos
The API replies:
[
{
"id": 1,
"done": false,
"task": "finish tutorial 0",
"due": null
},
{
"id": 2,
"done": false,
"task": "pat self on back",
"due": null
}
]
POST http://localhost:3000/todos
curl http://localhost:3000/todos -X POST \
-H "Content-Type: application/json" \
-d '{"task": "do bad thing"}'
Response is 401 Unauthorized:
{
"hint": null,
"details": null,
"code": "42501",
"message": "permission denied for relation todos"
}