PHPackages                             sdpmlab/anser - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. sdpmlab/anser

ActiveLibrary

sdpmlab/anser
=============

PHP microservice orchestration pattern library.

v0.2.6(2y ago)61464MITPHPPHP ^7.4||^8.0

Since Apr 17Pushed 2y ago1 watchersCompare

[ Source](https://github.com/SDPM-lab/Anser)[ Packagist](https://packagist.org/packages/sdpmlab/anser)[ RSS](/packages/sdpmlab-anser/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (3)Versions (17)Used By (0)

Anser: PHP Microservices Orchestration Library
==============================================

[](#anser-php-microservices-orchestration-library)

 [![logo](https://camo.githubusercontent.com/a06ede6c383f13b886d1a8d6224ae2c851e559679cacccb6524e9680e37bfb22/68747470733a2f2f692e696d6775722e636f6d2f327652416349302e706e67)](https://camo.githubusercontent.com/a06ede6c383f13b886d1a8d6224ae2c851e559679cacccb6524e9680e37bfb22/68747470733a2f2f692e696d6775722e636f6d2f327652416349302e706e67)

Anser is a PHP-based microservices orchestration library. You can use this library to manage connections and orchestrate your microservices. Through the Anser library, you can easily achieve the following goals:

- Abstract specific classes and implementations for each HTTP-based microservice, and Anser will not limit your communication mode.
- Quickly compose your microservices
- Write a microservices script with order
- Quickly adopt the SAGA Pattern to design your transaction logic
- Simple backup mechanism, transaction restore when service is interrupted

[正體中文文件](README_zh-TW.md)

Installation
------------

[](#installation)

Install Anser library via Composer:

```
composer require sdpmlab/anser
```

Quick Start
-----------

[](#quick-start)

### Microservices Connection List

[](#microservices-connection-list)

In your project, you must set the microservices connection list during the execution cycle. You can set it through the `ServiceList::addLocalService()` method. You can refer to the example we provide to create your microservices connection list, which will be the basis for all microservices connections.

```
namespace App\Anser\Config;

use SDPMlab\Anser\Service\ServiceList;

ServiceList::addLocalService("order_service","localhost",8080,false);
ServiceList::addLocalService("product_service","localhost",8081,false);
ServiceList::addLocalService("cart_service","localhost",8082,false);
ServiceList::addLocalService("payment_service","localhost",8083,false);
```

### Abstract Microservice

[](#abstract-microservice)

In Anser, you can abstract all endpoints of a microservice through the `SimpleService` class. We provide an example, you can refer to it to quickly create a microservice class:

```
namespace App\Anser\Services;

use SDPMlab\Anser\Service\SimpleService;
use SDPMlab\Anser\Service\ActionInterface;
use SDPMlab\Anser\Exception\ActionException;
use Psr\Http\Message\ResponseInterface;

class OrderService extends SimpleService
{
    protected $serviceName = "order_service";
    protected $retry      = 1;
    protected $retryDelay = 1;
    protected $timeout    = 10.0;

    /**
     * Get order by order_key
     *
     * @param integer $u_key
     * @param string $order_key
     * @return ActionInterface
     */
    public function getOrder(
        int $u_key,
        string $order_key
    ): ActionInterface {
        $action = $this->getAction("GET", "/api/v2/order/{$order_key}")
            ->addOption("headers", [
                    "X-User-Key" => $u_key
                ])
            ->doneHandler(
                function (
                    ResponseInterface $response,
                    ActionInterface $action
                ) {
                    $resBody = $response->getBody()->getContents();
                    $data    = json_decode($resBody, true);
                    $action->setMeaningData($data["data"]);
                }
            )
            ->failHandler(
                function (
                    ActionException $e
                ) {
                    log_message("critical", $e->getMessage());
                    $e->getAction()->setMeaningData([
                        "message" => $e->getMessage()
                    ]);
                }
            );
        return $action;
    }

    /**
     * Create order
     *
     * @param integer $u_key
     * @param integer $p_key
     * @param integer $amount
     * @param integer $price
     * @param string $orch_key
     * @return ActionInterface
     */
    public function createOrder(
        int $u_key,
        int $p_key,
        int $amount,
        int $price,
        string $orch_key
    ): ActionInterface {
        $action = $this->getAction("POST", "/api/v2/order")
            ->addOption("json", [
                "p_key"  => $p_key,
                "price"  => $price,
                "amount" => $amount
            ])
            ->addOption("headers", [
                "X-User-Key" => $u_key,
                "Orch-Key"   => $orch_key
            ])
            ->doneHandler(
                function (
                    ResponseInterface $response,
                    ActionInterface $action
                ) {
                    $resBody = $response->getBody()->getContents();
                    $data    = json_decode($resBody, true);
                    $action->setMeaningData($data["orderID"]);
                }
            )
            ->failHandler(
                function (
                    ActionException $e
                ) {
                    log_message("critical", $e->getMessage());
                    $e->getAction()->setMeaningData([
                        "message" => $e->getMessage()
                    ]);
                }
            );
        return $action;
    }

    /**
     * Delete order
     *
     * @param string $order_key
     * @param string $u_key
     * @param string $orch_key
     * @return ActionInterface
     */
    public function deleteOrderByOrchKey(
        string $u_key,
        string $orch_key
    ): ActionInterface {
        $action = $this->getAction('DELETE', "/api/v2/order")
            ->addOption("headers", [
                "X-User-Key" => $u_key,
                "Orch-Key"   => $orch_key
            ])
            ->doneHandler(
                function (
                    ResponseInterface $response,
                    Action $action
                ) {
                    $resBody = $response->getBody()->getContents();
                    $data    = json_decode($resBody, true);
                    $action->setMeaningData($data["data"]);
                }
            )
            ->failHandler($this->getFailHandler());
        return $action;
    }

    /**
     * Fail handler
     *
     * @return callable
     */
    protected function getFailHandler(): callable {
        return function (
            ActionException $e
        ) {
            log_message("critical", $e->getMessage());
            $e->getAction()->setMeaningData([
                "message" => $e->getMessage()
            ]);
        };
    }

}
```

You can directly refer to the [`Anser-Action`](https://github.com/SDPM-lab/Anser-Action) library to understand what mechanism Anser provides to handle microservices connections.

### orchestrate Microservices

[](#orchestrate-microservices)

In Anser, you can orchestrate your microservices through the `Orchestrator` class. We provide an example, you can refer to it to quickly create an orchestration class:

```
