《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的PostgREST 是一个独立的 Web 服务器,可将您的 PostgreSQL 数据库直接转换为 RESTful API。数据库中的结构约束和权限决定了 API 端点和操作。
影响速度的三个因素。首先,服务器是用Haskell编写的,使用 Warp HTTP 服务器(又名具有轻量级线程的编译语言)。接下来,它将尽可能多的计算委托给数据库,包括
最后,它通过 Hasql库有效地使用数据库
公开模式中的所有视图和表都可以被请求的活动数据库角色访问。它们暴露在一层深层路线中。例如,表格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 ASSELECT * 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 版本控制。
功能
默认情况下,创建函数时,执行它的权限不受角色限制。函数访问是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 functioncreate 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,请先解压缩压缩文件以获取可执行文件。
# For UNIX platformstar 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 managerpostgrest --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