gustavosantos / api-core
ApiCore 以简单和定制化的方式提供请求响应、异常和验证器(基于 Laminas 功能)。
Requires
- php: >=7.3.6
- ext-json: *
- gustavosantos/status-http: ^1.0
- jms/serializer: ^3.8
- laminas/laminas-diactoros: ^2.3
- psr/container: ^1.0
- symfony/validator: ^5.1
This package is auto-updated.
Last update: 2021-05-21 21:28:02 UTC
README
ApiCore 以简单和定制化的方式提供请求响应、异常和验证器。
这些功能在设计时考虑了在诸如 Zend Expressive 和 Mezzio 等框架中的使用。
安装
为了进行安装,请使用 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;