gfg/hek

此软件包已废弃,不再维护。未建议替代软件包。

Hek 插件,提供您的 Web 服务之间的集成(服务网关模式)

1.0.9 2016-10-21 17:26 UTC

README

Scrutinizer Code Quality Code Coverage Build Status Latest Stable Version Total Downloads License Forks Stars

简介

服务之间的通信从来都不是一件容易的事情。为了方便和保持一致,Hek 利用面向上下文的数据包装库 DTO-Context 确保数据的完整性和规范化,同时足够灵活,适用于任何类型的服务。

概念

这个概念相当简单:创建您的数据实体(数据包装器);映射您的服务执行的操作并为每个操作创建一个上下文。之后,您可以让 Hek 负责将信息传递给负责的组件。

Hek 是一个包含实现特定上下文使用的薄通信层的基文件库。它基于服务网关模式,Hek-Marketplace(使用 DTO-Marketplace)就是其实施的一个好例子。

结构

Exceptions //All the exceptions used in the library
├─ InvalidInput.php //Malformed Json
├─ MethodNotAllowed.php //When a service method that doesn't exist is requested
├─ ResponseInteface.php //Interface that all Hek implementations exceptions must implement
└─ RetryMessage.php //Exception used by the ApiClient

Interfaces //All the interfaces needed to create a Hek implementation
├─ Configuration.php //Some configurations needed for Hek to work properly
├─ Context.php //What is expected for a context to be used by Hek
└─ ServiceFactory.php //Hek must know how to create your services

ApiClient.php //Client that handles HTTP requests
CommandBus.php //Proxies the commands to the responsible objects
Manager.php //Handle the dependencies

使用示例

如上所述,该库是一个基础库,用于开发特定服务的通信层(服务网关)。我们将使用创建一个人、更新人员的姓名并接收创建确认的服务示例。我们将其称为 MyHek

为此,我们需要遵循以下步骤

  1. 创建数据包装器;
  2. 上下文;
  3. 服务工厂;
  4. 服务;
  5. 上下文工厂。

示例 1:直接实现(不在可组合库中分离)

建议结构

MyHek
    Datawrappers
    └─ Person.php
    Contexts
    ├─ Person
       ├─ Create.php
       └─ UpdateName.php
       └─ ConfirmCreate.php
    └─Factory.php
    Services
    ├─ Configuration.php
    ├─ Manager.php    
    └─ Person.php
└─ Factory.php

1. DataWrapper

<?php

namespace MyHek\DataWrapper;

use GFG\DTOContext\DataWrapper\Base;

/**
 * @SuppressWarnings(PHPMD.UnusedPrivateField)
 * @method string getName()
 * @method integer getHeight()
 * @method integer getWeight()
 * @method integer getAge()
 * @method string getNationality()
 * @method \MyHek\DataWrapper\Person setName(string $name)
 * @method \MyHek\DataWrapper\Person setHeight(integer $height)
 * @method \MyHek\DataWrapper\Person setWeight(integer $weight)
 * @method \MyHek\DataWrapper\Person setAge(integer $age)
 * @method \MyHek\DataWrapper\Person setNationality(string $nationality)
 */
class Person extends Base
{
    private $name;
    private $height;
    private $weight;
    private $age;
    private $nationality;
}

2. 上下文

创建人员上下文

<?php

namespace MyHek\Context\Person;

use GFG\Hek\Interfaces\Context as HekContext;
use GFG\DTOContext\Context\Base as BaseContext;

class Create extends BaseContext implements HekContext
{
    public function getHttpMethod()
    {
        return 'post';
    }

    public function getUrl()
    {
        return 'create-person';
    }

    /**
     * In this method, we'll use only the data that is needed for
     * this action
     */
    public function exportContextData()
    {
        $dataWrapper = $this->getDataWrapper();

        return $this->prepareExport([
            'name'        => $dataWrapper->getName(),
            'height'      => $dataWrapper->getHeight(),
            'weight'      => $dataWrapper->getWeight(),
            'age'         => $dataWrapper->getAge(),
            'nationality' => $dataWrapper->getNacionality()
        ]);
    }
}

更新名称上下文

<?php

namespace MyHek\Context\Person;

use GFG\Hek\Interfaces\Context as HekContext;
use GFG\DTOContext\Context\Base as BaseContext;

class UpdateName extends BaseContext implements HekContext
{
    public function getHttpMethod()
    {
        return 'put';
    }

    public function getUrl()
    {
        return 'update-name';
    }

    public function exportContextData()
    {
        $dataWrapper = $this->getDataWrapper();

        return $this->prepareExport([
            'name' => $dataWrapper->getName()
        ]);
    }
}

确认创建

<?php

namespace MyHek\Context\Person;

use GFG\Hek\Interfaces\Context as HekContext;
use GFG\DTOContext\Context\Base as BaseContext;

class ConfirmCreate extends BaseContext implements HekContext
{
    public function getHttpMethod()
    {
        return 'put';
    }

    public function getUrl()
    {
        return 'confirm-create';
    }

    public function exportContextData()
    {
        $dataWrapper = $this->getDataWrapper();

        return $this->prepareExport([
            // ...
        ]);
    }
}

3. 服务工厂

<?php

namespace MyHek;

class Factory implements GFG\Hek\Interfaces\ServiceFactory
{
    public function build(GFG\Hek\Interfaces\Context $context)
    {
        $parts = array_slice(explode('.', $context->getName()), -2, 1); // ['Person']
        $className = ucfirst(current($parts)); // Person
        $serviceName = "\MyHek\Services\{$className}";
        return new $serviceName;
    }
}

4. 服务

配置

<?php

namespace MyHek\Services;

use GFG\Hek\Interfaces;

class Configuration implements Interfaces\Configuration
{
    public function isEnabled()
    {
        return true;
    }

    public function getUserKey()
    {
        return 'myUserKey';
    }

    public function getBaseUrl()
    {
        return 'http://person.service.com';
    }

    public function getAccessToken()
    {
        return 'access token';
    }

    public function getHttpUser() 
    {
        return 'user'; // or false
    }

    public function getHttpPass()
    {
        return 'password'; // or false
    }
}

5. 上下文工厂

<?php

namespace MyHek\Context;

use GFG\Hek\DTO-Context\Factory\Base as BaseFactory;

class Factory extends BaseFactory
{
    const PERSON_CREATE        = 'person.create'; 
    const PERSON_UPDATENAME    = 'person.updatename'; 
    const PERSON_CONFIRMCREATE = 'person.confirmcreate'; 

    protected static $mappedContext = [
        self::PERSON_CREATE        => 'MyHek\Context\Person\Create',
        self::PERSON_UPDATENAME    => 'MyHek\Context\Person\UpdateName',
        self::PERSON_CONFIRMCREATE => 'MyHek\Context\Person\ConfirmCreate'
    ];

    public function getMappingList()
    {
        return self::$mappedContext;
    }
}

发送请求

<?php

use MyHek\Context\Factory;
use GFG\DTOContext\Manager;

$manager = (new Manager())->setFactory(new Factory());
$context = $manager->build(...);

示例 2:模块化实现,在组合库中保持上下文和hek实现分离