damiandev / ivy
为创建微服务而设计的PHP开发框架
Requires
- php: ^7.4 || ^8.0
- doctrine/orm: ^2.8
- filp/whoops: 2.*
- guzzlehttp/guzzle: ~6.0
- league/plates: ^3.4
- maximebf/debugbar: ^1.16
- php-di/php-di: dev-master
- phpoffice/phpspreadsheet: ^1.17
- symfony/http-foundation: ^5.2@dev
- vlucas/phpdotenv: ^5.1@dev
Requires (Dev)
- ext-mbstring: *
- doctrine/inflector: ^1.4|^2.0
- phpunit/phpunit: ^7
This package is auto-updated.
Last update: 2024-09-20 00:12:10 UTC
README
Ivy
Ivy是一个专门为以简单、灵活且特别经济的方式创建API而设计的框架。
基础
Ivy提出了一种简单的构建API的范例,以基于通信协议HTTP为基础,创建一个简单的信息流,用于访问和操作服务器端计算资源。Ivy的目标是能够从PHP最终类创建访问点,同时每个类都有一组执行和构建响应体的方法。
注意:重要的是指出,Ivy不基于REST架构,因为它有一个100%专注于生成关于输入请求构建标准的焦点。
Ivy标准
Ivy在输入请求中实施了一个标准,使用相同的结构来处理所有请求,这样我们可以更好地控制请求的构建,并在Ivy的正常流程中添加额外的信息和动作。
关于URL
要与应用程序交互,需要通过每个端点的通用URL进行操作,这使我们能够分割系统并识别每个案例所需的全部实体。这样,我们就有了一组可消费和分割的点,以实现特定的目标。
示例
如我们所见,我们有3个端点,每个端点都聚集了特定于端点的集合方法。
POST
Ivy实现了协议HTTP的唯一通信动词,目的是减少构建请求的复杂性,而将访问和与请求体的交互责任完全委托给请求体。
请求体
Ivy在所有输入请求中工作并实现Content-Type: multipart/form-data,这使我们能够控制发送的信息,并根据请求的URL中指定的端点特定方法来分割请求。
_method
这是一个必需的访问参数,它是每个端点内可用方法的字面表示。此参数确定每个请求将执行哪个操作。
_data
这是一个可选的请求参数,它以json格式包含一个数组,其中包含对执行要消费的方法的重要信息。
_filters (beta)
这是一个可选的请求参数,如果配置了它,则将对方法的响应应用一个特定的过滤器,这些可以是排序、搜索和选择过滤器。
文件处理
Ivy能够处理从客户端发送的文件,为了发送它们,重要的是要遵循请求体参数的约定。
示例
_image_name_image_1
_image_name_image_2
_document_pdf_name_document
_document_excel_name_document
第一步
需要注意的是,Ivy 实现了设计模式 Abstract Factory 或 抽象工厂,这允许通过一个 json 格式的配置文件创建端点和服务。通过这个配置文件,Ivy 执行端点的创建、参数配置和过滤器的应用。本文档还包含了一些重要信息,可以通过端点 docs 消费,这是唯一一个实现 HTTP GET 动词的方法和端点。
api.json
{
"name": "Ivy Api",
"version": "1.0.0",
"url": "https://:8000",
"endpoints": [
{
"name": "clientes",
"options": {
"class": "\\App\\Endpoints\\Clientes",
"methods": {
"todos":{
"function": "todos",
"permissions": "CLIENTE_READ"
},
"all":{
"function": "getUsers",
"permissions": "CLIENTE_READ"
},
"single":{
"function": "getUser",
"params": {
"id": "required"
},
"permissions": "CLIENTE_READ"
}
}
}
},
{
"name": "compras",
"options": {
"class": "\\App\\Actions\\Compras",
"methods": {
"all":{
"function": "getAll",
"permissions": "BUY_READ"
},
"single":{
"function": "getBuy",
"params": {
"id": "required"
},
"permissions": "BUY_READ"
}
}
}
}
]
}
本文档包含一个数组,存储了 API 的名称、版本和 URL,以及一系列端点。每个端点包含端点名称和选项列表。
每个端点的选项列表包含所需实例化的类的 namespace 和可用于消费的方法集合。
每个消费方法实现 4 条操作规则:
- function: 要执行的 PHP 函数名称 (_method)
- params: 执行函数所需的参数 (_data)
- permission: 用户执行函数所需的权限
- files: Ivy 可以接受的文件数量限制
services.json
{
"hostingerSMTP": {
"class": "\\App\\Services\\Hostinger",
"construct": {
"host": "smtp.hostinger.com",
"port": "430",
"user": "user",
"password": "123"
}
},
"firebaseClient": {
"class": "\\App\\Services\\Firebase",
"construct": {
"secret-key": "secret",
"site-key": "430"
}
},
"databaseA": {
"class": "\\App\\Services\\DatabaseA",
"construct": {
"host": "database.host",
"port": "360",
"user": "user",
"password": "123"
}
},
"databaseB": {
"class": "\\App\\Services\\DatabaseB",
"construct": {
"host": "database.host",
"port": "360",
"user": "user",
"password": "123"
}
}
}
本文档包含一个服务集合,这些服务将在端点方法执行上下文中可用,为我们提供了获取预构建和可用的实例的灵活性。
端点
Ivy 的端点是 PHP 的一个最终类,这些类由程序员可配置的集合方法组成,使程序员可以为每个方法提供简单的逻辑,从而消除从每个方法的实际功能中创建的单个责任。
示例 1
<?php namespace App\Endpoints;
use Core\Abstracts\EndpointsAbstract;
final class Cliente extends EndpointsAbstract
{
public function todos()
{
// Algo que hacer
}
public function crear()
{
// Algo que hacer
}
public function eliminar()
{
// Algo que hacer
}
public function editar()
{
// Algo que hacer
}
public function mostrarUno()
{
// Algo que hacer
}
public function importar()
{
// Algo que hacer
}
public function exportar()
{
// algo que hacer
}
}
如我们所见,端点是对系统实体的抽象,同时它们包含了一组由程序员定义有明确责任的方法。特别地,我们可以看到端点实现了标准的 REST 方法,以及用于导入和导出客户集合的两个额外方法。这种做法使程序员能够通过一系列自定义方法扩展每个端点,并提供了对每个方法的具体维护的灵活性。
信息获取
为了访问请求的信息,每个端点必须扩展一个抽象父类,该类提供了一系列有用的方法。该类在构造函数中使用了两个桥梁类来处理请求信息和可用于执行端点方法的可用服务。
EndpointsAbstract
<?php namespace Core\Abstracts;
use Core\Bridges\ServicesBridge;
use Core\Bridges\RequestBridge;
abstract class EndpointsAbstract
{
private ServicesBridge $serviceBridge;
private RequestBridge $requestBridge;
public function __construct(RequestBridge $requestBridge, ServicesBridge $servicesBridge)
{
$this->serviceBridge = $servicesBridge;
$this->requestBridge = $requestBridge;
}
public function getService($service)
{
return $this->serviceBridge->getService($service);
}
public function getData()
{
return $this->requestBridge->getData();
}
public function getParam($paramName)
{
return $this->requestBridge->getParam($paramName);
}
public function getFiles()
{
return $this->requestBridge->getFiles();
}
public function getFile($fileName)
{
return $this->requestBridge->getFile($fileName);
}
}
