cubadevops/flexi

尊重标准的灵活框架

安装: 3

依赖项: 0

建议者: 0

安全性: 0

星标: 4

关注者: 0

分支: 0

开放问题: 3

类型:项目

1.2.0 2024-06-02 00:00 UTC

README

Flexi是一个模块化的PHP框架,旨在简化可扩展和可维护应用程序的开发。它利用依赖注入(DI)、灵活的路由系统、CQRS和事件驱动架构。

目录

特性

  • 模块化与可扩展性:Flexi提供了一种模块化架构,促进代码组织和复用。其可扩展性允许开发者根据特定项目需求自定义和扩展功能。
  • 依赖注入:内置对依赖注入的支持简化了依赖项的管理和注入,增强了代码的可维护性和可测试性。Flexi中的DI使用容器以懒加载实例化方式管理服务。
  • 灵活路由:灵活的路由系统使得开发者可以轻松定义和管理HTTP请求处理,简化了复杂路由逻辑的开发,并支持中间件。
  • 事件驱动架构:Flexi的事件驱动架构允许事件监听器异步处理事件,促进应用程序设计中的松耦合和灵活性。
  • CQRS与可扩展性:支持命令查询责任分离(CQRS)促进了可扩展性和性能优化。结合异步处理等功能,Flexi简化了可扩展应用程序的开发,使其能够处理高流量和数据负载。
  • 通过JSON配置:Flexi中的配置通过JSON文件管理,便于定义服务、路由、事件、查询和命令。这种方法简化了配置管理,并促进了项目间的统一性。将实现Json Schema来验证配置文件。

结构

  • 核心src/目录包含构成框架的核心类和接口。
  • 模块modules/目录包含不属于核心框架的所有代码。每个模块是一个独立的目录,包含自己的控制器、服务和配置文件。可以添加到应用程序中的即插即用插件可以扩展其功能。
  • 配置src/Config/modules/*/Config目录包含框架的配置文件(路由命令查询事件监听器服务)。
  • 控制台bin/目录包含可以从命令行运行的控制台应用程序。(即将推出)

安装

您可以使用Composer安装Flexi框架

composer create-project cubadevops/flexi my-app

此命令在my-app目录中创建了一个最小化的启动模板应用程序。

安装后的步骤

要开始使用Flexi框架,请确保您

  • 配置您的Web服务器,使其指向项目根目录中的public目录。
  • 拒绝直接访问除public目录之外的所有目录。
  • 直接服务静态文件,并将所有其他请求路由到public目录中的index.php文件。
  • 设置.env文件,包含您的应用程序所需的环境变量。

配置完成后,浏览到您应用程序的URL以查看欢迎页面。如果您使用Docker的默认配置,您可以通过https://:8080访问应用程序。

配置

Flexi的配置通过JSON文件进行管理。这些文件定义了应用程序中使用的服务、路由、事件、查询和命令。

服务

服务在位于Config目录中的services.json文件中定义。该文件概述了每个服务应如何实例化,是直接实例化还是通过工厂方法。

示例

{
  "services": [
    {
      "name": "CubaDevOps\\Flexi\\Infrastructure\\Classes\\Configuration",
      "factory": {
        "class": "CubaDevOps\\Flexi\\Infrastructure\\Factories\\ConfigurationFactory",
        "method": "getInstance",
        "arguments": []
      }
    },
    {
      "name": "session",
      "alias": "CubaDevOps\\Flexi\\Domain\\Classes\\NativeSessionStorage"
    },
    {
      "name": "logger",
      "class": {
        "name": "CubaDevOps\\Flexi\\Infrastructure\\Classes\\PsrLogger",
        "arguments": [
          "@CubaDevOps\\Flexi\\Domain\\Classes\\InFileLogRepository"
        ]
      }
    },
    {
      "glob": "/modules/*/Config/services.json"
    }
  ]
}

注意

  • 使用alias键可以以不同的名称引用服务。
  • @为前缀的参数是其他服务的引用(也可以是别名)
  • ENV.为前缀的参数是环境变量的引用。
  • 没有@ENV.前缀的引号字符串被视为字符串值。
  • 所有其他值都视为标准的json_decode值。
  • 使用glob键可以从modules中包含服务。

路由

路由在routes.json文件中定义。每个路由指定HTTP方法、路径以及应处理请求的控制器。

示例

{
  "routes": [
    {
      "name": "health",
      "path": "/health",
      "method": "GET",
      "controller": "CubaDevOps\\Flexi\\Infrastructure\\Controllers\\HealthController",
      "parameters": [],
      "middlewares": [
        "CubaDevOps\\Flexi\\Infrastructure\\Middlewares\\AuthCheckMiddleware"
      ]
    },
    {
      "name": "404",
      "path": "/not-found",
      "method": "GET",
      "controller": "CubaDevOps\\Flexi\\Infrastructure\\Controllers\\NotFoundController"
    },
    {
      "glob": "/modules/*/Config/routes.json"
    }
  ]
}

注意

  • 如果您想附加中间件,则控制器应实现Psr\Http\Server\RequestHandlerInterface接口。然而,它们必须有一个handle方法,该方法接收一个Psr\Http\Message\ServerRequestInterface并返回一个Psr\Http\Message\ResponseInterface
  • 可选的parameters键用于定义应传递给请求的参数数量以及它们是否必需。
  • 可选的middlewares键用于定义在控制器之前应执行的中间件。它们按定义的顺序执行,如果它们直接返回响应或传递请求到下一个中间件,则可以停止执行链。
  • 使用glob键可以从modules中包含额外的路由定义。

事件和监听器

事件和监听器在listeners.json文件中定义。该文件将事件映射到相应的监听器。

示例

[
  {
    "event": "*",
    "listeners": [
      "CubaDevOps\\Flexi\\Application\\EventListeners\\LoggerEventListener"
    ]
  },
  {
    "glob": "/modules/*/Config/listeners.json"
  }
]

注意

  • event键可以是特定的事件名称或通配符*以监听所有事件。
  • 监听器类应实现CubaDevOps\Flexi\Domain\Interfaces\EventListenerInterface接口。

查询

查询在queries.json文件中定义。每个查询处理程序映射到特定的DTO和可选的CLI别名。

示例

{
  "handlers": [
    {
      "id": "CubaDevOps\\Flexi\\Domain\\DTO\\EmptyVersionDTO",
      "cli_alias": "version",
      "handler": "CubaDevOps\\Flexi\\Application\\UseCase\\Health"
    },
    {
      "glob": "/modules/*/Config/queries.json"
    }
  ]
}

注意

  • 处理程序应实现CubaDevOps\Flexi\Domain\Interfaces\HandlerInterface接口。

命令

命令在commands.json文件中以与查询类似的方式定义。

示例

{
  "handlers": [
    {
      "glob": "/modules/*/Config/commands.json"
    }
  ]
}

注意

  • 处理程序应实现CubaDevOps\Flexi\Domain\Interfaces\HandlerInterface接口。

使用

路由器

Router类负责管理路由并将请求分配给适当的控制器。

示例用法

use CubaDevOps\Flexi\Domain\Classes\Router;
use Psr\Http\Message\ServerRequestInterface;
use CubaDevOps\Flexi\Domain\Factories\ContainerFactory;

/** @var Router $router */
$router = ContainerFactory::getInstance()->get(Router::class); // or use router alias
$route = $router->getByName('home'); // Get a route by name
$route->getPath(); // Get the path of the route to pass to the template

事件系统

Flexi的事件系统基于EventBus模式。事件被分发到监听器,它们可以相应地处理它们。

示例

use CubaDevOps\Flexi\Domain\Interfaces\EventBusInterface;
use CubaDevOps\Flexi\Domain\Classes\Event;
use CubaDevOps\Flexi\Application\UseCase\Health;
use CubaDevOps\Flexi\Domain\Factories\ContainerFactory;
use CubaDevOps\Flexi\Domain\Classes\EventBus;

$eventBus = ContainerFactory::getInstance()->get(EventBus::class);
$event = new Event('health-check', Health::class, ['from' => $_SERVER['REMOTE_ADDR']);
$eventBus->notify($event);

CQRS

Flexi实现了CQRS模式,对命令和查询有单独的处理。

命令示例

use CubaDevOps\Flexi\Domain\Classes\CommandBus;

// Assume $command is a class that implements the DTOInterface
$commandBus->execute($command);

查询示例

use CubaDevOps\Flexi\Domain\Classes\QueryBus;

// Assume $query is a class that implements the DTOInterface
$result = $queryBus->execute($query);

控制器和响应

响应是PSR-7响应对象,可以从控制器或中间件返回。扩展了CubaDevOps\Flexi\Infrastructure\Classes\HttpHandler的控制器可以使用createResponse方法轻松构建响应。如果您没有扩展HttpHandler,则可以使用实现Psr\Http\Message\ResponseFactoryInterface接口的工厂来构建响应。Flexi使用GuzzleHttp\Psr7\HttpFactory作为默认工厂。

示例

namespace CubaDevOps\Flexi\Modules\Home\Infrastructure\Controllers;

use CubaDevOps\Flexi\Infrastructure\Classes\HttpHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class AuthenticatedController extends HttpHandler
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        if (!$this->queue->isEmpty()) { // This block allows to execute middlewares
            return $this->getNextMiddleware()->process($request, $this);
        }

        $response = $this->createResponse();
        $response->getBody()->write('Authorized');

        return $response;
    }
}

中间件

中间件是可以在控制器之前执行的类。它们可以修改请求、响应或停止执行链。中间件应实现Psr\Http\Server\MiddlewareInterface接口。

示例

namespace CubaDevOps\Flexi\Infrastructure\Middlewares;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class AuthCheckMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // Perform authentication logic here and stop the execution chain if necessary
        // or pass the request
        return $handler->handle($request);
    }
}

文档

文档可在网上获得,网址为https://flexi.cubadevops.com(建设中,尚未可用)。

贡献

欢迎贡献!请提交拉取请求或打开问题以讨论您想进行的任何更改。

许可证

Flexi 是一款开源软件,许可协议为 MIT 许可协议