PostgREST 将 PostgreSQL 数据库转换为 RESTful API

《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的PostgREST 是一个独立的 Web 服务器,可将您的 PostgreSQL 数据库直接转换为 RESTful API。数据库中的结构约束和权限决定了 API 端点和操作。

PostgREST 将 PostgreSQL 数据库转换为 RESTful API

PostgREST表现

影响速度的三个因素。首先,服务器是用Haskell编写的,使用 Warp HTTP 服务器(又名具有轻量级线程的编译语言)。接下来,它将尽可能多的计算委托给数据库,包括

  • 直接在 SQL 中序列化 JSON 响应
  • 数据验证
  • 授权
  • 组合行计数和检索
  • 单个命令中的数据发布 ( returning *)

最后,它通过 Hasql库有效地使用数据库

  • 保持数据库连接池
  • 使用 PostgreSQL 二进制协议
  • 无状态以允许水平缩放

表和视图

公开模式中的所有视图和表都可以被请求的活动数据库角色访问。它们暴露在一层深层路线中。例如,表格people的全部内容返回到

GET /people HTTP/1.1

没有深度/嵌套/路线。每个路由都提供 OPTIONS、GET、HEAD、POST、PATCH 和 DELETE 动词,完全取决于数据库权限。

水平过滤(行)

您可以通过在列上添加条件来过滤结果行。例如,返回 13 岁以下的人:

GET /people?age=lt.13 HTTP/1.1

您可以通过添加更多查询字符串参数来评估列上的多个条件。例如,返回 18 岁或以上学生:

GET /people?age=gte.18&student=is.true HTTP/1.1

对于更复杂的过滤器,您必须在数据库中创建一个新视图,或使用存储过程。例如,这是一个显示“今日故事”的视图,包括可能较旧的固定故事:

CREATE VIEW fresh_stories AS
SELECT *
  FROM stories
 WHERE pinned = true
    OR published > now() - interval '1 day'
ORDER BY pinned DESC, published DESC;

该视图将提供一个新端点:

GET /fresh_stories HTTP/1.1

逻辑运算符

AND默认情况下使用列上的多个条件进行评估,但您可以将它们OR与or运算符结合使用。例如,返回 18 岁以下或21 岁以上的人:

GET /people?or=(age.lt.18,age.gt.21) HTTP/1.1

要否定任何运算符,您可以在其前面加上notlike?a=not.eq.2或?not.and=(a.gte.0,a.lte.100)。

您还可以将复杂的逻辑应用于条件:

GET /people?grade=gte.90&student=is.true&or=(age.eq.14,not.and(age.gte.11,age.lte.17)) HTTP/1.1

全文检索

上面提到的fts过滤器有许多选项来支持灵活的文本查询,即选择普通搜索与短语搜索以及用于词干提取的语言。假设这tsearch是一个列tsvectormy_tsv类型的表。以下示例说明了这些可能性。

GET /tsearch?my_tsv=fts(french).amusant HTTP/1.1
GET /tsearch?my_tsv=plfts.The%20Fat%20Cats HTTP/1.1
GET /tsearch?my_tsv=not.phfts(english).The%20Fat%20Cats HTTP/1.1
GET /tsearch?my_tsv=not.wfts(french).amusant HTTP/1.1

使用websearch_to_tsquery需要至少 11.0 版本的 PostgreSQL,并且会在数据库的早期版本中引发错误。

架构结构

模式隔离

PostgREST 实例公开单个PostgreSQL 模式(数据库对象的命名空间)的所有表、视图和存储过程。这意味着私有数据或实现细节可以进入不同的私有模式并且对 HTTP 客户端不可见。

建议您不要在 API 架构上公开表。而是公开将内部细节与外界隔离的视图和存储过程。这允许您更改架构的内部结构并保持向后兼容性。它还使您的代码更易于重构,并提供了一种自然的方式来进行 API 版本控制。

PostgREST 将 PostgreSQL 数据库转换为 RESTful API

功能

默认情况下,创建函数时,执行它的权限不受角色限制。函数访问是PUBLIC— 可由所有角色执行(更多详细信息请参见PostgreSQL 权限页面)。这对于 API 模式并不理想。要禁用此行为,您可以运行以下 SQL 语句:

ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;

这将更改将来在所有模式中创建的所有函数的权限。目前没有办法将其限制为单一模式。在我们看来,无论如何,这是一个很好的做法。

之后,您需要明确授予函数的 EXECUTE 权限:

GRANT EXECUTE ON FUNCTION login TO anonymous;
GRANT EXECUTE ON FUNCTION signup TO anonymous;

您还可以将架构中所有函数的执行权限授予更高的特权角色:

安全定义器

函数以调用它的用户的权限执行。这意味着用户必须拥有执行过程执行的操作的所有权限。如果函数访问私有数据库对象,您的API 角色将无法成功执行该函数。

另一种选择是使用选项定义函数。然后只进行一次权限检查,调用函数的权限,函数中的操作将拥有函数本身的用户的权限。

-- login as a user wich has privileges on the private schemas

-- create a sample function
create or replace function login(email text, pass text) returns jwt_token as $
begin
  -- access to a private schema called 'auth'
  select auth.user_role(email, pass) into _role;
  -- other operations
  -- ...
end;
$ language plpgsql security definer;

安装

您可以从Homebrew 官方 repo安装 PostgREST 。

brew install postgrest

您可以从 nixpkgs 安装 PostgREST。

nix-env -i haskellPackages.postgrest

运行 PostgREST

如果您从发布页面下载 PostgREST,请先解压缩压缩文件以获取可执行文件。

# For UNIX platforms
tar Jxf postgrest-[version]-[platform].tar.xz

# On Windows you should unzip the file

现在您可以使用标志运行 PostgREST--help以查看使用说明:

# Running postgrest binary
./postgrest --help

# Running postgrest installed from a package manager
postgrest --help

# You should see a usage help message

PostgREST 服务器读取配置文件作为其唯一参数:

postgrest /path/to/postgrest.conf

# You can also generate a sample config file with
# postgrest -e > postgrest.conf
# You'll need to edit this file and remove the usage parts for postgrest to read it

—END—

开源协议:MIT license

开源地址:https://github.com/PostgREST/postgrest

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章