gustavosantos/api-core

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

ApiCore 以简单和定制化的方式提供请求响应、异常和验证器(基于 Laminas 功能)。

v1.0.2 2020-10-16 20:40 UTC

This package is auto-updated.

Last update: 2021-05-21 21:28:02 UTC


README

License Minimum PHP Version

ApiCore 以简单和定制化的方式提供请求响应、异常和验证器。

这些功能在设计时考虑了在诸如 Zend ExpressiveMezzio 等框架中的使用。

安装

为了进行安装,请使用 Composer

执行以下命令

composer require gustavosantos/api-core

配置

autoload 文件夹内,定义一个配置文件,结构如下

<?php

declare(strict_types=1);

return [
    "api_core" => [
        "default_code_error" => -1, # Define o código de erro interno padrão.
        "default_message_error" => "Ocorreu um erro inesperado na API!", # Define uma mensagem padrão para erros não tratados.
        "default_base_uri" => "https://:8081/", # Define a uri padrão para as respostas com Hateoas.
    ]
];

构建一个用于加载 ContainerInterface 的 Middleware,并在 pipeline 中实现它。

<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\LoadConfigData;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class LoadConfigDataMiddleware implements MiddlewareInterface
{
    public function __construct(ContainerInterface $container)
    {
        LoadConfigData::setContainer($container);
    }

    /**
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        return $handler->handle($request);
    }
}
# Adicione após RouteMiddleware

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

实现

Hateoas

为了在 API 成功响应中配置 Hateoas,只需在您的实体或 DTO 中使用 HateoasCore 的注解。

  • RestCore:

    属性 必需 描述
    params 接收一个 ParamsCor 数组
  • ParamsCore:

    属性 必需 描述
    title 任意文本
    rel 表示关系
    method HTTP 方法
    href 一个完整的 URL,它应该定义一个单一资源
  • ValueCore:

    属性 必需 描述
    key 用于内部参数映射

注意:在 href 中传入的值/名称必须与 key 相等。 key 必须与类的属性匹配。

示例

<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\Hateoas\Annotation\RestCore;
use ApiCore\Hateoas\Annotation\ParamsCore;
use ApiCore\Hateoas\Annotation\ValueCore;
use JMS\Serializer\Annotation\Type;

/**
 * @RestCore(params={
 *     @ParamsCore(title="Inserir usuário", rel="post_user", method="POST", href="v1/usuarios"),
 *     @ParamsCore(title="Consultar usuário por user_id", rel="get_user_by_user_id", method="GET", href="v1/usuarios/user_id", params={@ValueCore(key="user_id")})
 * })
 */
class User
{
    /**
     * @var int
     * @Type("int")
     */
    private $user_id;

    /**
     * @return int
     */
    public function getUserId(): int
    {
        return $this->user_id;
    }

    /**
     * @param int $user_id
     */
    public function setUserId(int $user_id): void
    {
        $this->user_id = $user_id;
    }
}

验证器

要使用 ValidatorCore,您可以直接使用它,也可以扩展它。由 ValidatorCore 验证的对象必须实现 ObjectCoreInterface

使用 Symfony 注解在类属性上添加限制。

示例

<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\Validation\ObjectCoreInterface;
use JMS\Serializer\Annotation\Type;
use Symfony\Component\Validator\Constraints\NotBlank;

class User implements ObjectCoreInterface
{
    /**
     * @var int
     * @Type("int")
     * @NotBlank(message="O campo user_id é obrigatório!")
     */
    private $user_id;
}
<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\Validation\ValidatorCore;

$user = new User();
(new ValidatorCore())->validateCore($user);

结果

{
    "status_code": 400,
    "error": [
        {
            "internal_message_error": "O campo user_id é obrigatório!"
        }
    ]
}

异常

要使用 ExceptionCore,您可以直接使用它,也可以扩展它。

  • Error:
    • status_code:适用于该问题的 HTTP 状态代码,表示为一个序列值;
    • code:特定于应用程序的错误代码,表示为一个序列值
    • message_error:关于错误的摘要/友好文本;
    • internal_message_error:面向开发者的错误摘要/文本,包括集成错误等;
    • trace_error:未处理的异常或错误堆栈跟踪;

注意:repeatMessage不会显示/序列化,它只定义是否需要在internal_message_error中重复message_error的值。

use ApiCore\Exception\Config;
use ApiCore\Exception\ExceptionCore;
use Http\StatusHttp;

throw new ExceptionCore((new Config())
                ->setStatusCode(StatusHttp::BAD_REQUEST)
                ->setMessageError("Ocorreu um erro ao processar sua solicitação, entre em contato com o suporte!")
                ->setInternalMessageError("O campo user_id é obrigatório!"));

结果

{
    "status_code": 400,
    "error": [
        {
            "message_error": "Ocorreu um erro ao processar sua solicitação, entre em contato com o suporte!",
            "internal_message_error": "O campo user_id é obrigatório!"
        }
    ]
}

响应

要使用JsonResponseCore,您可以直接使用它或使用JsonResponseCoreBuilder构建它。

<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\Response\JsonResponseCore;
use Http\StatusHttp;
use User;

$user = new User();
$user->setUserId(1);
$user->setName("Gustavo");

return new JsonResponseCore($user, StatusHttp::CREATED);

或者

<?php

declare(strict_types=1);

namespace SeuNamespace;

use ApiCore\Response\JsonResponseCoreBuilder;
use Http\StatusHttp;
use User;

$user = new User();
$user->setUserId(1);
$user->setName("Gustavo");

return (new JsonResponseCoreBuilder())
                ->setData($user)
                ->setStatusCode(StatusHttp::CREATED)
                ->build();

结果

{
    "status_code": 201,
    "data": {
        "user_id": 1,
        "name": "Gustavo"
    },
    "links": [
        {
            "title": "Inserir usuário",
            "rel": "post_user",
            "method": "POST",
            "href": "https://:8081/v1/usuarios"
        },
        {
            "title": "Consultar usuário por user_id",
            "rel": "get_user_by_user_id",
            "method": "GET",
            "href": "https://:8081/v1/usuarios/1"
        }
    ]
}

注意事项

错误
  • 初始化前不能访问:

    由于PHP 7.4引入了属性类型提示,因此特别重要为所有属性提供有效值,确保所有属性都有与声明的类型相对应的值。一个从未被分配的变量不是一个空值,而是一个处于未定义状态的变量,它永远不会与声明的任何类型相匹配。

    undefined !== null

    示例

    private $user_id = null; 

    或者

    private ?int $user_id = null;