定制 riskio/idempotency-module 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

riskio/idempotency-module

Composer 安装命令:

composer require riskio/idempotency-module

包简介

Zend Framework module ensuring at most once requests for mutating endpoints.

README 文档

README

Zend Framework module ensuring at most once requests for mutating endpoints.

Latest Stable Version Software License Build Status Total Downloads

While the inherently idempotent HTTP semantics around PUT and DELETE are a good fit for many API calls, what if we have an operation that needs to be invoked exactly once and no more? An example might be if we were designing an API endpoint to charge a customer money; accidentally calling it twice would lead to the customer being double-charged, which is very bad.

This is where idempotency keys come into play. When performing a request, a client generates a unique ID to identify just that operation and sends it up to the server along with the normal payload. The server receives the ID and correlates it with the state of the request on its end. If the client notices a failure, it retries the request with the same ID, and from there it’s up to the server to figure out what to do with it.

Stripe describes its solution in a blog post which provided the inspiration for this package.

Requirements

Installation

Idempotency module only officially supports installation through Composer. For Composer documentation, please refer to getcomposer.org.

You can install the module from command line:

$ composer require riskio/idempotency-module

After installation of the package, you have to copy the riskio_idempotency.global.php.dist file into your config/autoload folder and apply any setting you want.

  • source: vendor/riskio/idempotency-module/config/riskio_idempotency.global.php.dist
  • destination: config/autoload/riskio_idempotency.global.php

Zend Framework

In Zend Framework application, you must enable the module by adding Riskio\IdempotencyModule in your application.config.php file.

Zend Expressive

In Zend Expressive application, you must add the Riskio\IdempotencyModule\IdempotencyMiddleware middleware in config/pipeline.php file at the very first pipeline records.

<?php
use Riskio\IdempotencyModule\IdempotencyMiddleware;

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

Documentation

The module goal is to guarantee the safety of operations on mutating endpoints by allowing clients to pass a unique value with the special Idempotency-Key header.

The clients are in charge of creating the unique keys. The module always send back the same response for requests made with the same key, and keys can't be reused with different request parameters.

Idempotency key format validation

By default, the module uses V4 UUIDs but you can change validation rules using the config file seen above:

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

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

Storage of already performed requests

In order to keep track of requests performed with Idempotency-Key header, you have to specify a PSR-6 cache compliant service. Keys will expire after a delay related to the lifetime of your cache.

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

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

For instance, Stripe has defined that the keys expire after 24 hours.

Idempotent requests serialization/deserialization

For each idempotent request, the module creates an instance of Riskio\IdempotencyModule\IdempotentRequest that contains a checksum of the HTTP request performed and the related HTTP response in order to be stored and eventually retrieved in the future if the request is made more than once.

Accordindly, we must provide a serializer that will serialize and unserialize this class. By defaut, the module uses the Riskio\IdempotencyModule\Serializer\Serializer class but you can provide another one if you want.

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

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

Eligible HTTP methods

RFC7231 (substituting RFC2616) added two notions to HTTP methods:

  • A safe HTTP method is a method that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.
  • An idempotent HTTP method is a method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. For subsequent calls, the answer will be the same all the time.
Method Safe Idempotent
GET yes yes
HEAD yes yes
POST no no
PUT no yes
PATCH no no
DELETE no yes

Accordingly to the RFC, only POST and PATCH HTTP methods are not idempotent. Consequently, the module allows clients to use Idempotent-Key header only for these methods by default. However, you can configure another HTTP method list to meet your needs as below:

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

Idempotency key header customization

By default, the module uses Idempotency-Key header to submit unique tokens that guarantee idempotency of endpoints. If you want to use another header name for whatever reason, you can specify it as below:

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

Testing

$ vendor/bin/phpspec run

Credits

License

The MIT License (MIT). Please see License File for more information.

riskio/idempotency-module 适用场景与选型建议

riskio/idempotency-module 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 14 次下载、GitHub Stars 达 1, 最近一次更新时间为 2017 年 09 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「http」 「request」 「idempotency」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 riskio/idempotency-module 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 riskio/idempotency-module 我们能提供哪些服务?
定制开发 / 二次开发

基于 riskio/idempotency-module 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 14
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 2
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2017-09-16