pREST学习笔记

一、安装

Docker

$ docker pull prest/prest:latest

二、运行

Docker

$ docker run --rm -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=xxx.xxx.xxx.xxx\
        -e PREST_PG_PORT=5432 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=postgres \
        -e PREST_SSL_MODE=disable \
        -p 3000:3000 prest/prest:latest

三、Query Statements

使用 curl 进行操作:

$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items

增删改查

POST

$ curl -i -X POST http://127.0.0.1:3000/postgres/public/items -H "Content-Type: application/json" -d '{"number": "2", "name": "pencil", "price": "5"}'

-H:header,接收方自动识别转为 json

-d:data,post 需要有数据

DELETE

$ curl -i -X DELETE http://127.0.0.1:3000/postgres/public/items?name='notebook'

PATCH/PUT

$ curl -i -X PATCH http://127.0.0.1:3000/postgres/public/items?name='book' -H "Content-Type: application/json" -d '{"price": "30"}'

-d:可以只写需要更新的数据对应的值。

?:是定位符,如果没有,则全量更新,删除也是如此。

GET

filter参数
$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items?name=$eq'book'

官方文档里写的是:GET /DATABASE/SCHEMA/TABLE?FIELD=$eq.VALUE。实际上,. 需要删掉,否则获取不到数据。

问题

  • gt:大于,但是等于也能获取到?( lt 也有一样的问题)

  • ne:不等于,但是等于也能获取到?

  • incurl -i -X GET http://127.0.0.1:3000/postgres/public/items\?price\=$in\{'20.00','30.00'\}

  • nin:查询出来的反而是 in 的结果。

  • like:查询出来的是全部。curl -i -X GET http://127.0.0.1:3000/postgres/public/items\?name\=$like'%book'

query string
$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items\?_select={name}
$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items\?_count={name}
$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items\?_distinct\=true
$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items\?_order={price} # 默认增序

解决方法

-G 表示 GET

gt(gte、lt、lte同理)

$ curl -G -d 'price=$gt.15' http://127.0.0.1:3000/postgres/public/items

in、nin

$ curl -G -d 'price=$in.15,30' http://127.0.0.1:3000/postgres/public/items

具体的数组直接写在 $in. 后面,不需要写 []{}

like、ilike

$ curl -G -d 'name=$like.%25book' http://127.0.0.1:3000/postgres/public/items

如果使用 $like.%book,则会查询全部,不能正确匹配。经过查阅资料,发现应该是没有转义 %,因为 % 经过URL编码的结果是 %25。如果改成 %25 则会成功查询出匹配 name 字段尾部是 book 的所有数据。

遗留问题

为什么 ?price=$gt30 写在链接后面,查询出来的还包括等于的,而把参数写在前面就可以正确查询?

四、报错整理

1. [error] dial tcp 127.0.0.1:5432: connect: connection refused

代码

$ docker run -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=127.0.0.1 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=prest \
        prest/prest:latest

原因:连接被拒绝一般是没有这个 IP 地址或者端口。查看 docker 容器:

$ docker container ls -a

结果

CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS                        PORTS                                   NAMES
958000ab2099   postgres:alpine      "docker-entrypoint.s…"   6 days ago       Up 2 minutes                  5432/tcp                                some-postgres
3470bafff001   nginx:alpine         "/docker-entrypoint.…"   6 days ago       Exited (255) 6 hours ago      0.0.0.0:8080->80/tcp, :::8080->80/tcp   vigorous_cerf

发现 postgres 这个容器没有做 IP 映射,因此 -e PREST_PG_HOST=127.0.0.1 找不到相应 IP 地址。

于是考虑做 IP 映射,使用 -p 在运行 postgres 容器时将端口映射到宿主机的指定端口:

$ docker run --name some-postgres --rm -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres:alpine

再使用 docker ps -a 查看 docker 容器:

CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS                     PORTS                                       NAMES
44c4253e9fa2   postgres:alpine   "docker-entrypoint.s…"   5 seconds ago   Up 3 seconds               0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   some-postgres
3470bafff001   nginx:alpine      "/docker-entrypoint.…"   6 days ago      Exited (255) 6 hours ago   0.0.0.0:8080->80/tcp, :::8080->80/tcp       vigorous_cerf

发现这时已经有 iPhone 映射。解释一下这里的 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp 分别是什么意思。

0.0.0.0:5432->5432/tcp0.0.0.0 代表本机所有 IPV4 地址,因此本机所有 IPV4 地址 + 端口 :5432 都可以指向 postgres。

:::5432->5432/tcp:: 其实是 0:0:0:0:0:0:0:0 的缩写,代表本机所有 IPV6 地址。

127.0.0.1:所有网络号为 127 的地址都被称之为回环地址。

再执行以下命令:

$ docker run --rm -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=127.0.0.1 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=prest \
        prest/prest:latest

发现还是报错:[error] dial tcp 127.0.0.1:5432: connect: connection refused

原因:可以把这个 -e PREST_PG_HOST=127.0.0.1 理解成配置文件,所以肯定是从 prest 这个 docker 里进行寻找 postgres 进行连接,因此找不到。而运行的 postgres 容器则是跑在另一个 docker 里的,两者没有连接桥梁,所以根本跑不通。连接方式有两种,一种是将 postgres 映射到本机上,这样就相当于 postgres 在本机上操作写操作,然后 prest 通过这个端口操作读操作,就可以连接上 postgres 容器了。另一种则是使用两个 docker 容器直连,通过 network 配置 DNS,这样 host 只需要写成需要连接的 docker 容器起的名字就行,可以自动识别端口,如果使用 docker compose,可以直接 host 写成需要连接的 docker 容器起的名字,不需要单独设置 DNS。

参考docker容器的网络配置,允许docker可以被宿主机以外的其它主机访问以及局域网内可以直接访问docker容器ip

解决方法

  1. 使用 --network host 使得 prest 容器可以操作本机(不推荐)。
  2. 使用 WiFi 网络作为 HOST 地址。此方法有一个缺点,会走一遍路由器,没有方法一快。

执行以下命令查看 WiFi 地址:

$ ifconfig

找到这个:

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=400<CHANNEL_IO>
    ether 88:66:5a:3b:56:2a
    inet6 fe80::10d9:f421:90f7:60b8%en0 prefixlen 64 secured scopeid 0x6
    inet xxx.xxx.xxx.xxx netmask 0xfffffc00 broadcast 10.8.203.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: active

xxx.xxx.xxx.xxx 就是 WiFi 的 IP 地址。

然后执行:

$ docker run --rm -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=xxx.xxx.xxx.xxx \
        -e PREST_PG_PORT=5432 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=prest \
        prest/prest:latest

发现报错:

[error] pq: SSL is not enabled on the server

此时,只需要加一行 -e PREST_SSL_MODE=disable 关闭 SSL 就可以了。

$ docker run --rm -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=xxx.xxx.xxx.xxx \
        -e PREST_PG_PORT=5432 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=prest \
        -e PREST_SSL_MODE=disable \
        prest/prest:latest

发现又报错:

[error] pq: database "prest" does not exist

发现是自己写错了数据库名字,连接进入 postgres 里使用 \l 命令查看数据库名字:

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres

然后 exit 退出 postgres 数据库,再执行:

$ docker run --rm -e PREST_HTTP_PORT=3000 \
        -e PREST_PG_HOST=xxx.xxx.xxx.xxx \
        -e PREST_PG_PORT=5432 \
        -e PREST_PG_USER=postgres \
        -e PREST_PG_PASS=mysecretpassword \
        -e PREST_PG_DATABASE=postgres \
        -e PREST_SSL_MODE=disable \
        prest/prest:latest

就可以成功运行 prest 连接 postgres 了:

[prestd] Waiting for port xxx.xxx.xxx.xxx:5432 to become available...
[prestd] Ready hosting xxx.xxx.xxx.xxx to port 5432 !
2021/07/20 08:39:38 [warning] adapter is not set. Using the default (postgres)
2021/07/20 08:39:38 [warning] You are running pREST in public mode.
[prest] listening on 0.0.0.0:3000 and serving on /

2. HTTP/1.1 404 Not Found

执行命令:

$ curl -i -X GET http://127.0.0.1:3000/auth --user "username:password"

报错

HTTP/1.1 404 Not Found
Content-Type: application/json
X-Content-Type-Options: nosniff
Date: Thu, 22 Jul 2021 02:51:30 GMT
Content-Length: 34

{
    "error": "404 page not found"
}%

原因:没有 auth 这个路径,端口后面跟着的应该是 /DATABASE/SCHEMA/TABLE

解决方法

$ curl -i -X GET http://127.0.0.1:3000/postgres/public/items
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,002评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,777评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,341评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,085评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,110评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,868评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,528评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,422评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,938评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,067评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,199评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,877评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,540评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,079评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,192评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,514评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,190评论 2 357

推荐阅读更多精彩内容