风险IO/幂等性模块

Zend 框架模块,确保对突变端点的请求最多执行一次。

v1.0.0 2017-09-27 12:12 UTC

This package is auto-updated.

Last update: 2024-09-06 09:14:12 UTC


README

Zend 框架模块,确保对突变端点的请求最多执行一次。

Latest Stable Version Software License Build Status Total Downloads

虽然PUT和DELETE等幂等性HTTP语义对于许多API调用来说很好,但如果有一个操作需要恰好执行一次,那该怎么办?一个例子可能是我们设计一个API端点来收取客户的费用;不小心调用两次会导致客户被双重收费,这是非常糟糕的。

这就是“幂等性密钥”发挥作用的地方。当执行请求时,客户端生成一个唯一的ID来标识该操作,并将其与正常的有效负载一起发送到服务器。服务器接收到ID并将其与其端点上的请求状态相关联。如果客户端检测到失败,它将使用相同的ID重试请求,然后由服务器决定如何处理。

Stripe在博客文章中描述了其解决方案,这为这个包提供了灵感。

要求

安装

幂等性模块仅通过Composer官方支持安装。有关Composer文档,请参阅getcomposer.org

您可以从命令行安装模块

$ composer require riskio/idempotency-module

安装包后,您必须将riskio_idempotency.global.php.dist文件复制到您的config/autoload文件夹中,并应用您想要的任何设置。

  • 源:vendor/riskio/idempotency-module/config/riskio_idempotency.global.php.dist
  • 目标:config/autoload/riskio_idempotency.global.php

Zend 框架

在Zend框架应用程序中,您必须在application.config.php文件中添加Riskio\IdempotencyModule以启用该模块。

Zend Expressive

在Zend Expressive应用程序中,您必须在config/pipeline.php文件中添加Riskio\IdempotencyModule\IdempotencyMiddleware中间件作为第一个管道记录。

<?php
use Riskio\IdempotencyModule\IdempotencyMiddleware;

$app->pipe(IdempotencyMiddleware::class);

文档

该模块的目标是通过允许客户端使用特殊的幂等性密钥头传递唯一值,来确保对突变端点操作的安全性。

客户端负责创建唯一键。该模块总是对使用相同键发出的请求返回相同的响应,并且键不能与不同的请求参数一起重用。

幂等性键格式验证

默认情况下,该模块使用V4 UUIDs,但您可以使用上述配置文件更改验证规则

<?php
use Zend\Validator\Uuid as UuidValidator;

return [
    'riskio_idempotency' => [
        'idempotency_key_validator' => UuidValidator::class,
    ],
];

已执行请求的存储

为了跟踪带有幂等性密钥头的请求,您必须指定一个符合PSR-6缓存服务的服务。密钥将在与您的缓存寿命相关的延迟后过期。

<?php
use Symfony\Component\Cache\Adapter\NullAdapter as NullCacheAdapter;

return [
    'riskio_idempotency' => [
        'cache' => NullCacheAdapter::class,
    ],
];

例如,Stripe已定义密钥在24小时后过期。

幂等请求序列化/反序列化

对于每个幂等请求,该模块创建一个包含执行的HTTP请求的校验和和相关HTTP响应的Riskio\IdempotencyModule\IdempotentRequest实例,以便将来存储和检索,如果请求多次发出。

因此,我们必须提供一个序列化器来序列化和反序列化此类。默认情况下,模块使用 Riskio\IdempotencyModule\Serializer\Serializer 类,但您可以选择另一个类。

<?php
use Riskio\IdempotencyModule\Serializer\Serializer;

return [
    'riskio_idempotency' => [
        'serializer' => Serializer::class,
    ],
];

符合条件的HTTP方法

RFC7231(替代RFC2616)向HTTP方法添加了两个概念

  • 安全的HTTP方法是指不修改资源的方法。例如,在资源URL上使用 GETHEAD 应该永远不会更改资源。然而,这并不完全正确。这意味着:它不会更改资源的表示形式。仍然有可能,安全方法会改变服务器或资源上的某些内容,但这不应该反映在表示形式的差异中。
  • 幂等HTTP方法是指可以多次调用而不产生不同结果的方法。无论是调用一次还是多次,结果都应该相同。对于后续调用,答案将始终相同。

根据RFC,只有 POSTPATCH HTTP方法不是幂等的。因此,模块默认允许客户端只为这些方法使用 Idempotent-Key 标头。然而,您可以配置另一个HTTP方法列表以满足您的需求,如下所示

<?php
return [
    'riskio_idempotency' => [
        'http_methods' => ['PATCH', 'POST'],
    ],
];

幂等性键头定制

默认情况下,模块使用 Idempotency-Key 标头提交保证端点幂等的唯一令牌。如果您出于任何原因想要使用另一个标头名称,可以如下指定

<?php
return [
    'riskio_idempotency' => [
        'idempotency_key_header' => 'Idempotency-Key',
    ],
];

测试

$ vendor/bin/phpspec run

鸣谢

许可证

MIT许可证(MIT)。请参阅许可证文件获取更多信息。