交易记录#
之后 用户模拟 ,每个对 API resource 在事务内部运行。交易的顺序如下:
START TRANSACTION; -- <Access Mode> <Isolation Level>
-- <Transaction-scoped settings>
-- <Main Query>
END; -- <Transaction End>
访问模式#
访问模式决定了交易是否可以修改数据库。有两个可能的值:只读和读写。
不可能在只读事务中修改数据库。PostgREST使用这一事实在GET和HEAD请求中强制执行HTTP语义。请考虑以下事项:
CREATE SEQUENCE callcounter_count START 1;
CREATE VIEW callcounter AS
SELECT nextval('callcounter_count');
自.以来 callcounter
VIEW修改了序列,使用GET或HEAD调用它将导致错误:
curl "http://localhost:3000/callcounter"
HTTP/1.1 405 Method Not Allowed
{"code":"25006","details":null,"hint":null,"message":"cannot execute nextval() in a read-only transaction"}
表和视图的访问模式#
访问模式打开 表和视图 由HTTP方法确定。
Http方法 |
访问模式 |
---|---|
去拿,海德 |
只读 |
发布、修补、放置、删除 |
读写 |
功能上的访问模式#
作为RPC的功能 此外,还取决于功能 volatility 。
访问模式 |
|||
---|---|---|---|
Http方法 |
VOLATILE |
STABLE |
IMMUTABLE |
去拿,海德 |
只读 |
只读 |
只读 |
POST |
读写 |
只读 |
只读 |
备注
波动性标记是关于函数行为的承诺。PostgreSQL将允许您将修改数据库的函数标记为
IMMUTABLE
或STABLE
没有失败过。但是,由于只读事务,该函数在PostgREST下将失败。这个 期权方法 方法不会启动事务,因此它在这里不相关。
隔离级别#
每个事务都使用PostgreSQL默认隔离级别:已提交读。除非您修改 default_transaction_isolation 用于模拟的角色或功能。
ALTER ROLE webuser SET default_transaction_isolation TO 'repeatable read';
每个 webuser
获取其使用 default_transaction_isolation
设置为可重复读取。
或更改每个函数调用的隔离级别。
CREATE OR REPLACE FUNCTION myfunc()
RETURNS text as $$
SELECT 'hello';
$$
LANGUAGE SQL
SET default_transaction_isolation TO 'serializable';
事务作用域设置#
PostgREST使用与事务生存期相关的设置。这些可用于获取有关HTTP请求的数据。或修改HTTP响应。
你可以通过以下方式获得这些 current_setting
-- request settings use the ``request.`` prefix.
SELECT
current_setting('request.<setting>', true);
您可以将它们设置为 set_config
-- response settings use the ``response.`` prefix.
SELECT
set_config('response.<setting>', 'value1' ,true);
请求路径和方法#
路径和方法存储为 text
。
SELECT current_setting('request.path', true);
SELECT current_setting('request.method', true);
请求角色和搜索路径#
因为. 用户模拟 ,PostgREST制定了标准 role
。你可以通过不同的方式获得这一点:
SELECT current_role;
SELECT current_user;
SELECT current_setting('role', true);
响应标头#
您可以设置 response.headers
若要向HTTP响应添加标头,请执行以下操作。例如,下面的语句将向响应添加缓存头:
-- tell client to cache response for two days
SELECT set_config('response.headers',
'[{"Cache-Control": "public"}, {"Cache-Control": "max-age=259200"}]', true);
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache, no-store, must-revalidate
请注意, response.headers
应设置为 array 单键对象而不是单个多键对象。这是因为像这样的头 Cache-Control
或 Set-Cookie
设置多个值时需要重复。对象不允许重复的键。
备注
PostgREST提供了标题,如 Content-Type
, Location
等可以用这种方式覆盖。请注意,无论被重写的 Content-Type
响应头,则内容仍将转换为JSON,除非您使用 媒体类型处理程序 。
响应状态代码#
您可以将 response.status
以覆盖PostgREST提供的默认状态代码。例如,以下函数将替换默认的 200
状态代码。
create or replace function teapot() returns json as $$
begin
perform set_config('response.status', '418', true);
return json_build_object('message', 'The requested entity body is short and stout.',
'hint', 'Tip it over and pour it out.');
end;
$$ language plpgsql;
curl "http://localhost:3000/rpc/teapot" -i
HTTP/1.1 418 I'm a teapot
{
"message" : "The requested entity body is short and stout.",
"hint" : "Tip it over and pour it out."
}
如果状态代码为标准,则PostgREST将完成状态消息( I'm a teapot 在本例中)。
模拟角色设置#
PostgreSQL应用连接角色 (authenticator )设置。此外,PostgREST还应用 impersonated roles 设置为事务作用域设置。这允许对角色进行的操作进行更细粒度的控制。
例如,考虑 statement_timeout 。它允许您中止任何花费超过指定时间的语句。默认情况下,它处于禁用状态。
ALTER ROLE authenticator SET statement_timeout TO '10s';
ALTER ROLE anonymous SET statement_timeout TO '1s';
使用上述设置,所有用户都会获得10秒的全局语句超时 anonymous 用户的超时时间为1秒。
具有特权上下文的设置#
默认情况下,不会应用具有需要权限的上下文的设置。这样我们就不会导致权限错误。有关更多详细信息,请参阅 Understanding Postgres Parameter Context 。
但是,从PostgreSQL 15开始,您可以通过以下方式授予这些设置的权限:
GRANT SET ON PARAMETER <setting> TO <authenticator>;
功能设置#
除了……之外 模拟角色设置 ,PostgREST还将应用函数设置作为事务作用域设置。这允许函数设置覆盖模拟角色和连接角色设置。
CREATE OR REPLACE FUNCTION myfunc()
RETURNS void as $$
SELECT pg_sleep(3); -- simulating some long-running process
$$
LANGUAGE SQL
SET statement_timeout TO '4s';
在调用上述函数时(请参见 作为RPC的功能 ),则语句超时将为4秒。
备注
目前,只有 statement_timeout
应用于函数。
主查询#
交易结束#
如果事务没有失败,它将始终以提交结束。除非 DB-TX-END 配置为在任何情况下或有条件地使用 交易结束首选项 。这对于测试目的很有用。
正在中止事务#
任何数据库故障(如失败的约束)都将导致事务回滚。你也可以 RAISE an error inside a function 以引起回滚。
预请求#
预请求是一个可以在 事务作用域设置 都已设置,并且在 主查询 。它通过以下方式启用 数据库-请求前 。
这提供了修改设置或引发异常以阻止请求完成的机会。
通过预请求设置标头#
例如,让我们为来自Internet Explorer(6或7)浏览器的所有请求添加一些缓存头。
create or replace function custom_headers()
returns void as $$
declare
user_agent text := current_setting('request.headers', true)::json->>'user-agent';
begin
if user_agent similar to '%MSIE (6.0|7.0)%' then
perform set_config('response.headers',
'[{"Cache-Control": "no-cache, no-store, must-revalidate"}]', false);
end if;
end; $$ language plpgsql;
-- set this function on postgrest.conf
-- db-pre-request = custom_headers
现在,当您对表或视图发出GET请求时,您将获得缓存头。
curl "http://localhost:3000/people" -i \
-H "User-Agent: Mozilla/4.01 (compatible; MSIE 6.0; Windows NT 5.1)"