dotcubed.io/laravel-rad-mvc

RAD (快速应用开发) MVC

0.2 2024-04-20 17:47 UTC

This package is auto-updated.

Last update: 2024-09-20 18:42:06 UTC


README

此仓库使常规的Laravel安装能够使用基于API项目的RAD(快速应用开发)方法。

通过使用命名约定来自动触发模型方法,通过错误处理封装它们,通过表单请求进行验证,并通过资源进行转换,可以减少代码量并实现更快的开发时间。

对于基于API项目的MVC(模型-视图-控制器)的常规使用流程是:路由 > 控制器 > 模型 > 响应。

此库允许使用相同的流程,但更简洁,因为控制器方法被替换为可以解析和识别需要触发的模型方法的魔法调用并返回其值的调用。

如果需要实际使用控制器方法,只需在控制器上创建它,就可以使用常规流程。

如何使用

请求流程

路由指向控制器/方法。此控制器和方法的名称将定义要获取、实例化和触发的表单请求、资源和模型。

在请求/响应过程中,您可以使用表单请求来验证数据,并使用资源来格式化要返回的数据。

初始配置

为了使控制器能够操作请求,它需要扩展此库自己的控制器,如下所示:

class MyNewController extends \Dotcubed\LaravelRadMvc\Controllers\ApiController

当路由击中控制器时,它将触发魔法方法解析。

命名约定

为了使此结构正常工作,需要遵守一些命名约定。

以下示例说明了执行更新特定项目的补丁方法的Project模型场景。

以下文件与此相关

  • 调用updateProject方法在Projects控制器上的路由
  • 名为Projects控制器的控制器
  • 名为Project的模型
  • 名为UpdateProject请求的表单请求
  • 名为UpdateProject资源的资源

请注意,以某种形式,控制器和方法的名称被用来为所有涉及的文件设置标准。

对此标准进行更深入的了解,我们有以下内容

  • 资源使用方法名,但使用驼峰命名法(UpdateProject)并带有资源后缀,并存储在以模型名称命名的文件夹中(\app\Http\Resources\Project\UpdateProjectResource.php

路由

路由配置是Laravel的基本标准。您将其指向特定的控制器和它将调用的方法。

路由中的每个命名参数将按它们找到的顺序发送到方法,并将请求数据作为最后一个参数发送。在下面的示例中,updateProject方法将接收第一个参数projectUuid,第二个参数将是另一个参数,第三个将是验证后的响应数据。

Route::patch(
	'/project/{projectUuid}/abcd/{anotherParameter}',
	[
		App\Http\Controllers\Api\v1\ProjectsController::class,
		'updateProject'
	]
)->name('project.updateProject');

控制器

控制器应使用复数实体名称的标准Laravel命名约定(Projects),并存储在常规Http文件夹中。由于这是一个仅限API的项目,它存储在一个版本化的API文件夹中。

它还应扩展\Dotcubed\LaravelRadMvc\Controllers\ApiController,以便任何不在控制器上的方法都可以通过模型进行解析。

文件路径:\app\Http\Api\v1\Controllers\ProjectsController.php

<?php
namespace App\Http\Controllers\Api\v1;

class ProjectsController extends \Dotcubed\LaravelRadMvc\Controllers\ApiController
{
}

模型

模型应遵循Laravel的命名规范,实体使用单数形式(Project),并保存在Models文件夹中(\app\Models\Project.php)。将要触发的方法应该是静态的,并且与路由指向的名称完全一致。如果模型返回实际数据,则这些数据将通过资源(如果存在)进行解析。

文件路径:app\Https\Models\Project.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Project extends Model
{
	/**
	* @param array<string, string> $projectData
	*/
	public static function updateProject(
		string $projectUuid,
		string $anotherParameter,
		array $data
	): Project {
		$project = self::where('uuid', $projectUuid)->firstOrFail();
		$project->update($data);

		...
	
		//here as example to showcase the Resource functionality
		return $project;
	}

表单请求

表单请求是可选的,如果存在,将被用于验证从请求中来的数据。

表单请求应遵循以下命名约定

  • 文件路径:app\Http\Requests\

它还应扩展此库中的自定义AbstractRequest。这样,在特定的响应情况(如422)中,响应可以格式化。

请注意,在文件名中使用的命名方法是驼峰命名法,以避免更改Laravel中的文件命名约定。这意味着文件名不会是 updateProjectRequest.php,而是 UpdateProjectRequest.php

文件路径:\app\Http\Requests\Project\UpdateProjectRequest.php

<?php

namespace App\Http\Requests\Project;

use App\Http\Requests\AbstractRequest;
use Illuminate\Validation\Rule;

class UpdateProjectRequest extends AbstractRequest
{
	/**
	* Determine if the user is authorized to make this request.
	*/
	public function authorize(): bool
	{
		return  true;
	}
 
	/**
	* Get the validation rules that apply to the request.
	*
	* @return  array<string, array<int, string>>
	*/
	public function rules(): array
	{
		return [
			'name' => [
				'required',
				'string',
			],
			'description' => [
				'required',
				'string',
			],
		];
	}
}

资源

如果存在资源,将用于解析模型方法返回的数据,并为其准备JSON响应。如果不存在资源,则从模型方法发送回来的数据将原样发送到响应中。

表单请求使用以下命名约定

  • 文件路径:app\Http\Resources\

与表单请求一样,资源也将使用驼峰命名法。这意味着文件名不会是 updateProjectResource.php,而是 UpdateProjectResource.php

文件路径:\app\Http\Resources\Project\UpdateProjectRequest.php

<?php

namespace App\Http\Resources\Project;

use Illuminate\Http\Resources\Json\JsonResource;

/**
* @mixin \App\Models\Project
*/
class GetProjectResource extends JsonResource
{
	/**
	* Transform the resource into an array.
	*
	* @return  array<string, mixed>
	*/
	public  function toArray($request): array
	{
		return [
			'uuid' => $this->uuid,
			'name' => $this->name,
			'description' => $this->description,
		];
	}
}

代码流程

对于给定的示例,此库底层的逻辑如下

  • 如果Project控制器存在名为updateProject的方法,它将执行控制器方法并运行请求的常规工作流程
  • 如果Project控制器中不存在名为updateProject的方法,则
    • 根据路由中使用的控制器复数名称推断出模型单数名称。例如。
      • 如果控制器名称为ProjectsController,则推断模型名称为Project(单数)
      • 控制器名称为UserCheckBookController将推断模型名称为UserCheckBook
    • 检查是否存在名为推断出的名称的实际模型,位于 \app\Models\Project.php
    • 检查是否存在名为updateProject的方法
    • 检查是否存在名为 \app\Http\Requests\Project\UpdateProjectRequest.php 的表单请求
      • 如果存在表单请求,则使用此表单请求触发请求验证
    • 触发模型中的updateProject方法,并存储其返回值(如果有)
    • 检查是否存在位于 \app\Http\Resources\Project\UpdateProjectResource.php 的资源
      • 如果存在资源,则将模型方法的返回值传递到该资源
    • 使用标准响应格式返回响应

日志记录

所有用于获取、验证和触发所有相关元素的逻辑的每一步都记录在默认日志通道中,作为 INFO 日志条目。