API 模块提供 RESTful API 接口服务,并集成了 Swagger/OpenAPI 文档生成功能,便于接口文档的维护和测试。项目采用 DTO(Data Transfer Object)模式来处理请求参数和响应数据,提供了一套完整的解决方案。
使用 DTO 模式开发 API 有以下优势:
- 自动参数验证:通过属性注解自动验证请求参数
- Swagger 文档自动生成:根据 DTO 结构自动生成 API 文档
- 代码复用:同一 DTO 可用于参数验证、文档生成和业务处理
- 类型安全:强类型约束,减少运行时错误
- 清晰结构:明确的数据结构定义,便于维护
- 自动转换:支持与模型对象的自动转换
用于处理 API 请求参数,继承 BaseRequestDTO:
<?php
namespace app\api\controller\form\example;
use WebmanTech\DTO\Attributes\ValidationRules;
use WebmanTech\DTO\BaseRequestDTO;
final class ExampleCreateForm extends BaseRequestDTO
{
/**
* 用户名
* @example admin
*/
#[ValidationRules(required: true, maxLength: 64)]
public string $username;
/**
* 密码
* @example 123456
*/
#[ValidationRules(required: true, maxLength: 64)]
public string $password;
/**
* 名称
* @example 测试用户
*/
public string $name;
public function handle()
{
// 处理业务逻辑
// 可以使用 $this->toArray() 获取所有参数
// 返回处理结果
}
}用于定义 API 响应结构,继承 BaseResponseDTO:
<?php
namespace app\api\controller\form\example;
use WebmanTech\DTO\BaseResponseDTO;
final class ExampleListSearchFormResult extends BaseResponseDTO
{
public function __construct(
public int $count,
/**
* @var Model[]
*/
public array $list,
) {
}
}- 在
app/api/controller/form/目录下创建 DTO 类 - 继承
BaseRequestDTO - 定义公共属性作为请求参数
- 使用注解定义验证规则
- 实现
handle()方法处理业务逻辑
<?php
namespace app\api\controller;
use app\api\controller\form\example\ExampleCreateForm;
use OpenApi\Attributes as OA;
use Webman\Http\Response;
use WebmanTech\Swagger\DTO\SchemaConstants;
#[OA\Tag(name: '示例接口')]
final class ExampleSourceController
{
#[OA\Post(
path: '/crud',
summary: '新建',
x: [
// 关键:通过这个注解自动生成文档
SchemaConstants::X_SCHEMA_REQUEST => ExampleCreateForm::class . '@handle',
],
)]
public function store(): Response
{
// 一行代码完成参数验证、文档生成和业务处理
return json_success(
ExampleCreateForm::fromRequest()
->handle()
);
}
}对于路径参数,使用 RequestPropertyInPath 注解:
<?php
use WebmanTech\DTO\Attributes\RequestPropertyInPath;
use WebmanTech\DTO\BaseRequestDTO;
final class ExampleUpdateForm extends BaseRequestDTO
{
// 从路径参数中获取 id
#[RequestPropertyInPath]
public int $id;
public ?string $name = null;
public function handle()
{
// 业务逻辑
}
}通过 Trait 实现分页功能:
<?php
namespace app\api\controller\form\common;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
trait PaginationTrait
{
/**
* 分页大小
*/
public int $limit = 10;
/**
* 当前页
*/
public int $page = 1;
protected function getWithPage(Builder $query): LengthAwarePaginator
{
return $query->paginate($this->limit, ['*'], 'page', $this->page);
}
}在 DTO 中使用:
<?php
use app\api\controller\form\common\PaginationTrait;
use WebmanTech\DTO\BaseRequestDTO;
final class ExampleListSearchForm extends BaseRequestDTO
{
use PaginationTrait;
public string $username;
public function handle(): ExampleListSearchFormResult
{
$query = Model::query();
if ($value = $this->username) {
$query->where('username', $value);
}
// 使用分页
$paginator = $this->getWithPage($query);
return new ExampleListSearchFormResult(
count: $paginator->total(),
list: $paginator->items(),
);
}
}使用 DTO 模式时,Swagger 文档会根据 DTO 结构自动生成:
#[OA\Post(
path: '/crud',
summary: '新建',
x: [
// 通过这个配置自动生成请求和响应文档
SchemaConstants::X_SCHEMA_REQUEST => ExampleCreateForm::class . '@handle',
],
)]启动服务后,可通过 /api/openapi 路径访问 Swagger UI 界面
启动服务后,可通过 /api/openapi/dto-generator 访问 DTO 代码生成器界面
API 模块有专门的异常处理器,会在 config/exception.php 中配置:
return [
'api' => [
\app\exception\handlers\ExceptionHandlerApi::class
]
];异常处理器会自动将验证失败等异常转换为统一的 API 响应格式。